Prepaired statements in Zend_Db insert query - mysql

I currently use Zend_Db to manage my queries
$stmt = $db->prepare("INSERT INTO test (ID_Test) VALUES (:ID)");
$stmt->bindParam(':ID', 4, PDO::PARAM_INT);
$stmt->execute();
But this does seem to work throwing an error "Fatal error: Cannot pass parameter 2 by reference"
What am I doing wrong?

bindParam wants parameter two to be a variable, so it can reference or "link to" the variable instead of copying it, making it better for larger variables but annoying in your case, try:
$stmt = $db->prepare("INSERT INTO test (ID_Test) VALUES (:ID)");
$id = 4;
$stmt->bindParam(':ID', $id, PDO::PARAM_INT);
$stmt->execute();

Related

What's the best way to fetch an array

Alright, so I believe that there is a better way that I can fetch an array from the database, here's the code right now that I have.
$id = 1;
$userquery = mysql_query("SELECT * FROM login WHERE id='$id'");
while($row = mysql_fetch_array($userquery, MYSQL_ASSOC)) {
$username = $row['username'];
$password = $row['password'];
$email = $row['email'];
}
So If I am not wrong, you want a better way to get all the returned rows from mysql in a single statement, instead of using the while loop.
If thats the case, then I must say mysql_ drivers do not provide any such functionality, which means that you have to manually loop through them using foreach or while.
BUT, since mysql_ is already depricated, you are in luck! you can actually switch to a much better and newer mysqli_ or the PDO drivers, both of which DO actually have functions to get all the returned rows.
For mysqli_: mysqli_result::fetch_all
For PDO : PDOStatement::fetchAll
Eg.
mysqli_fetch_all($result,MYSQLI_ASSOC);
// The second argument defines what type of array should be produced
// by the function. `MYSQLI_ASSOC`,`MYSQLI_NUM`,`MYSQLI_BOTH`.
Like the comments already told you: PHP's mysql driver is deprecated. And you should use prepared statements and parameters.
for example in PDO your code would look something like this:
//connection string:
$pdo= new PDO('mysql:host=localhost;dbname=my_db', 'my_user', 'my_password');
//don't emulate prepares, we want "real" ones:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
//use exception-mode if you want to use exception-handling:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$id = 1;
//it's always better to strictly use backticks for db-names (db, tables, fields):
$sql = "SELECT * FROM `login` WHERE `id` = :id";
try
{
//create your prepared statement:
$stmt = $pdo->prepare($sql);
//bind a parameter and explicitly use a parameter of the type integer (in this case):
$stmt->bindParam(":id", $id, PDO::PARAM_INT);
//execute the query
$stmt->execute();
}
catch(PDOException $e)
{
exit("PDO Exception caught: " . $e->getMessage());
}
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$username = $row['username'];
$password = $row['password'];
$email = $row['email'];
}
here you go: your PHP-MySQL routine is save against SQL-injections now and no longer uses deprecated PHP-functions! it's kinda state of the art ;)

Cannot set NULL with PDO

I know there are other posts on this topic but they don't answer the basic question. The previous answers all say to use PDO::PARAM_NULL but doesn't that remove the entire reason for using PDO anyway?
Here is my code:
$sql = "INSERT INTO users_address (uid,street1,street2,city,state,region,postalcode,country) VALUES (?,?,?,?,?,?,?,?)";
$stmt = $this->db->conn_id->prepare($sql);
$stmt->bindParam(1, $uid, PDO::PARAM_INT);
$stmt->bindParam(2, $street1, PDO::PARAM_STR);
$stmt->bindParam(3, $street2, PDO::PARAM_STR);
$stmt->bindParam(4, $city, PDO::PARAM_STR);
$stmt->bindParam(5, $state, PDO::PARAM_STR);
$stmt->bindParam(6, $region, PDO::PARAM_STR);
$stmt->bindParam(7, $postalcode, PDO::PARAM_STR);
$stmt->bindParam(8, $country, PDO::PARAM_STR);
$stmt->execute();
Not all of these values are required so sometimes they are null. Both varchar and int database fields have default=null. How can I prepare this so that if a variable happens to be null, the null gets inserted? All of the other answers I have seen pass NULL for the second parameter but how do I know at run time it is a null?
To be really clear. I do not want to implicitly insert a null. I want to insert a variable which MAY be a null if the user did not complete the form. Not all fields are required on the form. For example, in this example, $street2.
In SQL, or at least standard SQL and most SQL flavours —yeah, I'm looking at you, Oracle— NULL is a special value that is completely different from empty strings. In SQL code you use the NULL keyword to represent the former and empty quotes for the latter.
Your input comes from HTML forms. HTML forms are always submitted as plain text: you don't have anything else, no numbers, no dates... and of course no nulls. Whenever you need an actual NULL, you need some post-processing. Happily, PDO will convert PHP nulls to SQL nulls:
$stmt->bindValue(6, $region!='' ? $region : null, PDO::PARAM_STR);
PDO (and SQL) are just unaware of HTML and won't do it for you.
I've also replaced your bindParam() with bindValue() to make it all less verbose.
Use PARAM_NULL to insert a null value or the other params you already have:
if (!isset($uid) || strlen($uid) == 0) {
$stmt->bindParam(1, null, PDO::PARAM_NULL);
} else {
$stmt->bindParam(1, $uid, PDO::PARAM_INT);
}

mysqli to pdo simple select statement

I just converted some MySQL to mysqli, but realized I do not have access to the mysqlnd driver with my server setup. So, I need to now convert to PDO which I have available.
I am trying to convert the following to PDO, but there is no bind_result available in PDO from what I have read. I need to use a prepared statement for this as there is user input.
$stmt = $mysqli->prepare("SELECT user,pass FROM test_users WHERE user = ?");
// bind params
$stmt->bind_param('s', $_POST['username']);
// execute prepared statement
$stmt->execute();
// Bind result variables
$stmt->bind_result($ruser, $rpass);
// fetch values
$stmt->fetch();
// close statement
$stmt->close();
Can anyone help out quick? Here is what I have, but not sure how to retrieve the resulting values into useable variables...
$stmt = $db->prepare("SELECT user,pass FROM test_users WHERE user = ?");
// bind params
$value = $_POST['username'];
// execute prepared statement
$stmt->execute($value);
// stmt now holds results, but how can I retrieve them into useable values?
// ?
// close statement
$stmt->closeCursor();
You need to make yourself familiar with arrays. They are no less "useable" than regular variables.
And sometimes arrays even more usable, especially in your case.
$stmt = $db->prepare("SELECT user, pass FROM test_users WHERE user = ?");
$stmt->execute([$_POST['username']]);
$row = $stmt->fetch();
Now $row contains the row returned by query. Now you can test if any data returned and then use it.
For the password check you can use it this way
if ($row && $row['pass'] === whatever_hash_used($_POST['password']]))
{
unset($row['pass']);
$_SESSION['user'] = $row;
// etc
}
You can return values from a PDO query with the PDOStatement::fetch method. There are various ways of fetching the data, such as into an array, into an object, and into a lazy-loading object. The simplest of these, and the most appropriate in your circumstance, is an array. In this case, you need to use the PDO::FETCH_ASSOC constant.
$results = $stmt->fetch(PDO::FETCH_ASSOC);
You can then access $results['user'] and $results['pass'].
A nice way of improving this would be to fetch $user and $pass variables rather than an array. This can be done with the list construct:
list($user, $pass) = $stmt->fetch(PDO::FETCH_NUM);
The other problem with your code (as Your Common Sense may or may not be pointing out in the comments: it's a little hard to tell) is that your code to bind the variables isn't quite right. PDOStatement::execute expects an array:
$stmt->execute(array($value));
$stmt->execute([$value]); // from PHP 5.4
In my opinion, the nicer way to do this is with named parameters:
$stmt = $db->prepare('SELECT user, pass FROM test_users WHERE user = :user');
$stmt->bindParam(':user', $_POST['username']);
$stmt->execute();
list($user, $pass) = $stmt->fetch(PDO::FETCH_NUM);

How to display the values returned by count in SQL

i keep having this error "mysql_fetch_array() expects parameter 1 to be resource, null given in" when i try to display the returned value of count in sql. heres my code.
$query="SELECT med_rec_ID, COUNT(med_rec_ID)
FROM med_issue
WHERE MONTH(issue_date) = MONTH('2013-02-05')
GROUP BY med_rec_ID";
$result= mysql_query($query);
while($count = mysql_fetch_array($display3)){
echo $count[0];
}
i have tried to run the query in sql alone it displays 2 columns (the med_rec_ID, and the COUNT). guys how do i display the count and fix the error too?
First of all, don't use mysql_* functions since they're deprecated. Use mysqli or PDO.
Secondly, look at what you're passing into the fetch_array function.
You probably want to do something like:
$link = mysqli_connect("localhost", "admin", "pass", "db_name");
$result = mysqli_query($link, $sql);
while($row = $result->fetch_array(MYSQLI_ASSOC)){
$medIds[] = $row['med_rec_ID'];
...
}
Then fix the count by giving it an alias.
Please note that you should actually store how you access the DB in a more secure manner, but I use this only to illustrate the example. Here's a pretty good post: How to create global configuration file?
Is your query even executing? that error will happen if mysql_query doesnt return the resource, in case query fails
$query="SELECT med_rec_ID, COUNT(med_rec_ID) as C FROM med_issue where MONTH(issue_date) = MONTH('2013-02-05') GROUP BY med_rec_ID";
$result= mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_assoc($result))
{
echo $row["C"];
}
Note: Please do not use mysql_* functions anymore
Give it an alias:
SELECT
med_rec_ID,
COUNT(med_rec_ID) TheCount
FROM med_issue
where MONTH(issue_date) = MONTH('2013-02-05') GROUP BY med_rec_ID
then you can select that column TheCount inside the while loop with $row['TheCount'], also use lope through the $result:
$result = mysql_query($query);
while($row = mysql_fetch_array($result)){
echo $row['TheCount'];
}

PDO returning MySQL error with bindParam

Hey Guys I'm running this little function here
function getBeaches() {
$request=Slim::getInstance()->request();
$args=filter_var_array(func_get_args(),FILTER_SANITIZE_STRING);
$sql="SELECT * FROM beaches WHERE state=:state AND city=:city";
// var_export($args); die();
// array ( 0 => 'wa', 1 => 'seattle', )
try {
$db = getConnection();
$stmt = $db->prepare($sql);
$stmt->bindValue('state', $args[0], PDO::PARAM_STR); //should bind wa
$stmt->bindValue('city', $args[1], PDO::PARAM_STR); //should bind seattle
$stmt->execute();
$stmt = $db->query($sql);
$beaches = $stmt->fetchObject();
$db = null;
echo '{"map": ' . stripslashes(json_encode($beaches)) . '}';
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
/* {"error":{"text":SQLSTATE[42000]: Syntax error or access violation:
* 1064 You have an error in your SQL syntax; check the manual that
* corresponds to your MySQL server version for the right syntax to use
* near ':state AND city=:city' at line 1}}
*/
}
And am getting the error I commented at the bottom, trying to run this like so
mysql$ SELECT * FROM beaches WHERE state='wa' AND city='seattle';
May be this rings some bells?
You need the semicolons before your param names: (Not 100% true, see edit)
$stmt->bindValue(':state', $args[0], PDO::PARAM_STR); //should bind wa
$stmt->bindValue(':city', $args[1], PDO::PARAM_STR); //should bind seattle
From the PHP docs on PDOStatement::bindValue():
Parameter identifier. For a prepared statement using named placeholders, this will be a parameter name of the form :name. For a prepared statement using question mark placeholders, this will be the 1-indexed position of the parameter.
EDIT
As #jeroen has pointed out the problem (the same one in your pastebin) that you overwrite the $stmt variable before you get the data from it. In you code the problem is around the 17th line:
$stmt->execute(); // $stmt now has query results (from the query with parameters bounded)
$stmt = $db->query($sql); // You redo the query. Now $stmt has no query results and no parameters are bound
$beaches = $stmt->fetchObject(); // Statement assumes you want to execute query and does so but not parameters are bound
You can remedy this by changing the above lines to:
$stmt->execute();
$beaches = $stmt->fetchObject();
Not sure if it helps, but I always used bindParam over bindValue. If you chose to do so, modify your binders as such:
$stmt->bindParam(':state', $args[0], PDO::PARAM_STR);
$stmt->bindParam(':city', $args[1], PDO::PARAM_STR);
Other than that, everything you're doing looks fine to me.