I\'m converting to PDO and Im using prepared statements, I want to bind my result as so $stmt->bind_result($email_count);
so i am able to put this into an if
For people who come here seeking a literal answer.
Use bindColumn
PDOStatement::bindColumn — Bind a column to a PHP variable
using the example from the same source :
function readData($dbh) { $sql = 'SELECT name, colour, calories FROM fruit'; try { $stmt = $dbh->prepare($sql); $stmt->execute(); /* Bind by column number */ $stmt->bindColumn(1, $name); $stmt->bindColumn(2, $colour); /* Bind by column name */ $stmt->bindColumn('calories', $cals); while ($row = $stmt->fetch(PDO::FETCH_BOUND)) { $data = $name . "\t" . $colour . "\t" . $cals . "\n"; print $data; } } catch (PDOException $e) { print $e->getMessage(); } } readData($dbh);
Yet you don't need to count either. Please, avoid unnecessary actions - they only bloat and obfuscate your code for no reason.
Think first, what you need from the query? Do you really need to count? No. What you actually need is just a flag - if user exists or no. So, make a query to return such a flag.
$stmt = $this->pdo->prepare("SELECT 1 FROM users WHERE email=?");
$stmt->execute(array($_POST['email']));
$exists = $stmt->fetchColumn();
Same goes for all the other parts of code
//escape the POST data for added protection
You don't actually "escape" any data in this code block and add no protection. Yet I see absolutely no point in inserting NULL as email. Are you sure you really want it?
Here's my custom function:
function bindColumns($stmt, $columns){
if(!is_array($columns)) $columns=array($columns);
$count=count($columns);
for($i=0;$i<$count;$i++) $stmt->bindColumn($i+1, $columns[$i]);
}
And usage (variables by reference):
bindColumns($stmt, array(&$worker_id, &$password, &$salt));
For quickly retrieving a value from something like a SELECT COUNT()
query, have a look at PDOStatement::fetchColumn, eg
$stmt = $pdo->prepare('SELECT COUNT(1) FROM users WHERE email = :email');
$stmt->bindParam(':email', $email);
$stmt->execute();
$email_count = $stmt->fetchColumn();
I'd also like to offer some further advice. You shouldn't be creating a PDO
connection in your class constructor. This means that every time you instantiate a class extending Database
, you create a new connection. Instead, pass the PDO
instance as a dependency, eg
abstract class Database {
/**
* @var PDO
*/
protected $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
}
The same goes for your User::insert
method. Try to pass any required parameters via method arguments. If you ever want to start writing unit tests for your classes, this will be invaluable
public function insert($email) {
$stmt = $this->pdo->prepare('SELECT COUNT(1) FROM users WHERE email = :email');
$stmt->bindParam(':email', $email);
$stmt->execute();
$email_count = $stmt->fetchColumn();
// and so on
And finally, for PHP only files, omit the closing PHP tag ?>
. This will save you from accidentally including whitespace at the end of your files that may be sent to the browser.