mysqli bind param data types - php

I’m currently working on a small set of database access and management classes in php. while trying to understand our well known mysqli better, I still fail to understand why and how variable-types defined in mysqli_stmt::bind_param could and would enhance security/utility within the current application.
The advantages of having a mysql statement going on are clear. Query and values are submitted on two different paths and that of course makes the application more secure and more error proof! But what happens to these variables… are these checked prior by php or after on in mysql?
Is it just mysqli being lazy for doing something like?
!is_numeric($v) && ( !is_null($v) || $v != “NULL”) ? “‘$v’” : $v
Or is there any var type definition on the mysql side which I don’t know?
“PREPARE stmt_name FROM … “;
“SET #var1 = 3”;
“SET #var2 = ‘foo’”;
“EXECUTE stmt_name USING #var1, #var2”;
It doesn’t seem there’s much going on this values. quite anything passed as a string is evaluated properly… then why bother?
There’s another side-question even though related to this one: is there any way to replicate mysqli’s way of sending blob string in packets?
Thanks bye

As nobody has given an answer yet... i do have one now! The data-type definition within bind_param does noting more than adding those quotes to the query, although, variables are bound at a lower level than a php script could be ever capable of! formally going though any different path apart from mysqli/pdo would mean to transfer all the data by strings!
thats it, cheers!

Related

PHP+Mysql : update not work if use '&' contain WHERE

This code not work :
UPDATE `test` SET `done`='1' WHERE `name`='x_&_y'
But this is work :
UPDATE `test` SET `done`='1' WHERE `name`='x_y'
Both of code return 1 value but first code not work and table not updated !
PHP code :
$value = 'x_&_y'; // send by $_GET['value']
$value = htmlspecialchars(trim($value),ENT_QUOTES,'UTF-8');
UPDATE `league` SET `leagueUpdateDone`='1' WHERE `leagueCountry`='$value';
The problem is you're running your query wrong. Never, ever use htmlspecialchars on input if you're trying to match things. & is a reserved character in HTML, it will be mangled.
Your final query looks like:
'x_&_y'
Instead use prepared statements with placeholder values, like this:
$stmt = $db->prepare('UPDATE `league` SET `leagueUpdateDone`='1' WHERE `leagueCountry`=?');
Then bind values against that. The procedure varies in implementation based on your use of mysqli or PDO.
Note: htmlspecialchars is only used for displaying HTML. Keep the content in your database as neutral as possible, never pre-escaped. You want to treat everything in your database as raw, escaping it for the context it's used in, be that JSON, HTML, email or otherwise, on a case-by-case basis. If you presume it's HTML that can make life very ugly if you need to undo that and re-do it for JSON, for example.
I don't know where you learned that htmlspecialchars technique, but it's highly probable this is cargo cult programming where incantations are used without their purpose being fully understood. This is a common problem with a lot of YouTube tutorial-type training where they drown you in code but offer very little in the way of theoretical foundation or practical explanations.
I'm trying not to be too hard on you here, you're just trying to learn, but it's important to understand the code you're using instead of just using it because someone told you to. Try to dig a little deeper, look up the documentation on the methods you're using. PHP has a fantastic manual with a comments section full of people helping to clarify any misunderstandings.

MySQL / PHP - Storing parameters in a database table: Good or bad idea?

So far I store all the relevant parameters that I need for my website as variables in a php file; then I point to this file through a requirestatement in each page that needs those parameters.
This is most of times good and easy to mantain, but sometimes I need to change those variables "on the fly" and I feel the need of some sort of web-panel where I can change them even more easily (I'm thinking to a web page with a form to update the parameters).
So I've created a table in my MySQL database to store parameters (basically, this table has two columns: ParamName and ParamValue; I've stored the parameter names as a varchar without the $ sign at the beginning), in order to create the web-panel I've in my mind.
I was thinking to extract all the parameters names and values using this query:
$query=$mysqli->query('select * from parameters');
while($row=mysqli_fetch_assoc($query)) {
$ParamName=$row["ParamName"];
$$ParamName=$row["ParamValue"]; }
Is this a good or a bad idea?
What are the main issues I could encounter doing so (in terms of security, too)?
How deprecable and dangerous is the use of $$ParamName?
I'd better change my mind or can I proceed this way?
EDIT: I changed mysql_ syntax into mysqli_ as suggested.
Using arbitrary values in a database as variable references is highly risky. What you'd want to do is fetch the data from your key/value store into a self-contained associative array and use that instead.
You also do not want to be using mysql_query for anything these days. Please, put that thing away.
If the parameters are all constants that will not be changed over time, it is faster to use a single file that stores them as constants in a simple associative array.
If these parameters will change, using a database that specializes in key-value stores might be more useful for you instead of using a standard relational database.
If you cannot change your database from a relational database, or you are not changing the values often, it would be faster to cache them using something like memcached.

How to use values from one stored procedure into another?

For eg
I have a SP which give a result when i, CALL A1();
i fetch the result and store in $a.
But when I call another SP CALL A2('$a'); It is not executing. Showing Array() when I run the program
When you compose the SQL command "CALL A2('$a');" in PHP, the parser first expands the $a variable within your double-quoted string literal. However, as documented under Converting to string:
Arrays are always converted to the string "Array"
Therefore PHP interprets the string that is to be sent to MySQL as "CALL AS('Array');", which is obviously the root of your problem. Note also that allowing PHP to expand variables into SQL commands in this fashion is dangerous: see #deceze's blog article The Great Escapism (Or: What You Need To Know To Work With Text Within Text) to understand this better; and then How can I prevent SQL injection in PHP? to understand how variables should (generally) be passed from PHP to SQL.
However, in this case, the fix is not so straightforward. Since MySQL does not have an array datatype, even if you did properly serialise the array then it would only recognise the serial form (which will not be easy to use in your A2 procedure).
It should also be noted that stored procedures don't really "return" anything. Whilst they can output zero or more resultsets, resultsets can't be used as an input to another stored procedure. The normal workaround is to store the resultset (e.g. in a temporary table) and then later access that as required.
That said, it is very rare indeed that such an arrangement is necessary. Usually people attempt such things because they're trying to use SQL as a procedural language, whereas it is a very powerful declarative language. If you explain what it is that your procedures are collectively trying to do, I very much suspect that someone will be able to write a single SQL command to do the whole thing.

What's the best way to compare variable string equality in PHP/MySQL?

I'm trying to check a string passed through the URL and get back all results from a MySQL database where that string is a match.
I send different queries based on the input, but the one in question looks basically like this (it's really much longer):
if ($projectsname) {$result = mysql_query("SELECT item FROM items WHERE projectname=$projectsname",$db)}
The issue is that $projectsname is a string. All my other queries return an integer and work fine. But in this case I can't get it to give me a proper result in the actual PHP code unless I put it in quotes, and here's how I did that:
$projectsname = (isset($_GET['projectname']) && !empty($_GET['projectname'])) ? '"'. $_GET['projectname'] .'"' : 0;
...by appending the quotes to the data that creates the variable. And that works. It just seems wrong to me.
Is there a better way of making this comparison?
(I wish I could say this was a newbie question, but it's something I've often had trouble with in my years as a designer who tries to code.)
Feel free to edit the question if you know better terminology than I have used here (and let me know what your edits were--I'm having a hard time phrasing the question.).
if ($projectsname) {$result = mysql_query("SELECT item FROM items WHERE projectname='$projectsname'",$db)}
You need to quote strings that you pass to mysql.
Run
echo "SELECT item FROM items WHERE projectname=$projectsname";
to see what query you're actually sending.
Also read up about mysql_real_escape_string and about SQL injections in general. Consider the following example of a very typical SQL injection your code is prone to:
$projectsname = "123 OR 1=1";
echo "DELETE FROM items WHERE projectname=$projectsname";
Using pure PHP for complete application projects is highly discouraged. It puts the coder in the position of worrying about elementary problems such as escaping queries, validating form data, security, templating, loading libraries, etc., etc. Instead of worrying about the program logic the coder puts too much time worrying about the syntax. Only newbies do that. We don't because time is money for us.
My recommendation: use framework. I personally recommend Codeigniter or Zend. Believe me it'll save you a lot of headache.

How to enable auto mysql real escape to all queries?

I'm running php 5.2.13 and i have an app that contains tons of files but they all calling one file at the beginning, i want to put some line in that file to automatically mysql real escape any query, because i don't want to go across every file and change code.
Thanks!
I don't know how well that would work. What you really need is to escape the input not things like table names, fields, etc. If you pass the entire query to an escape, I'd be willing to bet you'd find a good number of queries that will fail because it will turn things like
select * from tablename where name = 'foo'
into
select * from tablename where name = \'foo\'
Which would choke.
And, having a wrapper function in your code helps a lot (assuming you don't want to use a framework, etc). If you have "mysql_query()" littered around your code, you probably are in for a bit of work to change it up. If you can't/don't-want-to adopt a framework, at least wrap it in a function of your own, like "db_query()" like this:
function db_query($query,$and,$other,$arguments)
{
mysql_query( ... ); // you can change this to some other database later if you want
}
I did that in a project a few years ago and it helped a ton when I wanted to log some errors. I just added it to that function instead of having it in 200 places in the code.
But even that won't really help if you didn't escape input properly in the first place. In that case your only option is to take some time and fix it.
Hans has some good suggestions. But i think the bottom line is youre going to have to modify a lot of code. There is no magic bullet on this one. Whoever wrote it should have known better, and now you my friend are going to pay the price. Personally if youre going to have to go in and manually edit i would urge you to switch to PDO or mysqli. That way you can make use of prepared statements which will handle the escaping of variables for you provided you use them correctly.
If you have a large project, and need to change the data access, I would suggest to move to an ORM, my personal pick is Propel.
With that you would solve the whole escaping sql's problem, would make your app more scalable and you could also reverse your database diagram in order to generate the classes needed for Propel.
Propel will give you benefits like transactions, parameters and many more, so you should reaally think about it.
Best regards
Take note that it's not queries that you will want to escape, it's user supplied variables that are to be included in the query (unless you're writing malformed SQL yourself on purpose). So what you can do is to run mysql_real_escape_string() on, say, the $_POST array with array_map(), provided that you are not going to use that array for anything else.
mysql_real_escape_string() is still only the second best solution to the issue anyway. I you can use prepared statements (AKA parametrized queries) and you're home free.

Categories