PHP different results of pg_escape_bytea() when connecting to postgresql - php

Code:
echo pg_escape_bytea(45);
Result:
45
Code:
pg_connect ("host=$host dbname=$db user=$user password=$pass");
echo pg_escape_bytea(45);
Result:
\x3435
I don't want to change the result. How can I do that?
Please help!

SHORT ANSWER:
Never call the pg_escape_bytea function before pg_connect.
LONG ANSWER:
The pg_escape_bytea function is charset-aware function.
Function definition:
pg_escape_bytea ([ resource $connection ], string $data ) : string
As you can see from the funnction definition, you can pass a $connection as the first parameter. You can obtain this connection as a result from the pg_connect or pg_pconnect functions. However, I don't know how to obtain this "connection resource" from a PDO object.
Every connection has a charset associated with it. So when you pass a connection as the first parameter to pg_escape_bytea it will "read" the associated charset and encode the result accordingly.
If you don't pass the connection as the first parameter, then the pg_escape_bytea function will simply use the latest PostgreSQL connection.
And here is the problem:
If you call the pg_escape_bytea before you connect to your PostgreSQL database (using pg_connect or pg_pconnect or PDO ...) then the pg_escape_bytea function WILL NOT KNOW how to encode the result!
If you connect to your database and then call the pg_escape_bytea function with the exactly same input data it may return different output because the charset of the latest PostgreSQL connection changed!
SOLUTION:
So I think the easiest workaround is simply to never call the pg_escape_bytea function before pg_connect function (or other "connect" functions / PDO) because it will simply doesn't know how to encode the result properly.
PS: If you want to experiment with different outputs, you can change the charset like this:
$pdo->query("SET NAMES UTF8")

From the manual:
When you SELECT a bytea type, PostgreSQL returns octal byte values
prefixed with '\' (e.g. \032). Users are supposed to convert back to
binary format manually.
So after the connection is made, you need to deal with it manually.

Related

which mysqli query need mysqli_connect

Connection file is as below
$host="localhost";
$username="root";
$password="123";
$database = "order";
$con = mysqli_connect($host, $username, $password, $database);
$sel_db=mysqli_select_db($con,$database) or die("Cannot Select Database");
In each file I include above connection file
My older code for mysql is like
mysql_query("select * from order_detail");
and new query for mysqli is as below
mysqli_query($con,"select * from order_detail");
Above query required $con for connection
and mysql_fetch_array($var) becomes mysqli_fetch_array($var) it does not required $con
mysql_real_escape_string($var) becomes mysql_real_escape_string($con,$var);
So my question is that which query required $con as connection
The mysql functions implicitly used the last connection that was made if no connection was explicitly given. Note that you already could pass in a connection, even to the old function as you can read here. This behavior is confusing and error prone, so fortunately they made that more explicit in the mysqli functions.
I'm not sure that is the main reason though. It probably might have more to do with the fact that mysqli also has an object syntax, and that one syntax wraps another. The $con variable in the procedural version and the object instance in the objective version both serve the same purpose: telling the function/method which connection to use. Actually, the doc says that the connection parameter for mysqli_query is a mysqli object instance, so mysqli_query might just be implemented like this as a wrapper function to make it easier to convert your code from mysql to mysqli:
function mysqli_query($link, $query, $resultmode = MYSQLI_STORE_RESULT) {
return $link->query($query, $resultmode);
}
If you didn't understand anything I said in this last paragraph, don't worry, it's not really important. ;)
Anyway, while mysql_query performs a query on a connection, mysql_fetch_array fetches values from a query result. The $var your pass to it already contains all the information it needs. It doesn't need a connection at that point, so there is no need to pass it as an argument. There is no mysqli_fetch_array by the way. Instead you should use mysqli_stmt_fetch, to which the same applies: it doesn't need a connection, but a statement object (mysqli_stmt), which represents the query result.
Many of the mysqli functions have the same or similar parameters as their predecessors, but there may be differences. So for every function you use, I'd check the official documentation.
And also, I'd use an IDE or editor that will help you with the function syntax by providing built in code insight. Netbeans for PHP is a quite elaborate one that can be used for free, but there are even better ones (like PHPStorm) if you can spend some money.
PS: If you use prepared statements, you can get rid of mysql_real_escape_string completely.

Connect to mysqli with a string?

I have a function that return a string (with the database credentials), this string called $conn_db is like this:
host= localhost ;username= root ;password= 123456 ;database= test ;
now in my function for establish a database connection if I pass the value like so:
mysqli_connect($host, $username, $password, $dbname)
all working good but. If I pass the connection string only:
mysqli_connect($conn_db)
an exception is returned in the:
if (mysqli_connect_errno())
{
throw new Exception("Can't establish db connection");
}
isn't possible use a connection string instead of 4 variables in mysqli_connect?
Not possible. mysqli_connect() expects multiple arguments. When you do mysqli_connect($db_conn), you're passing ONE argument. The mysqli library, and underlying mysql driver, are NOT going to parse that string to try and extract whatever other parameters are necessary. You can't embed multiple values in a single argument either, and expect that to make sense.
Since you only provide $db_conn, that's what MySQL will try to use as the hostname (argument #1), and try to do a DNS lookup on some nonsensical "username=foo&password=bar"-type hostname, which will obviously fail.
If you want to use a single string/argument, then switch to PDO. Its constructor allows for such things.

Why check the return of mysql_real_escape_string()

In every blog/article/Q&A I have read, nobody suggested to check the value returned by mysql_real_escape_string().
The way I see it, this check is very important to ensure data consistency, because if this function fails, the value inserted in the database would be a false possitive: a boolean FALSE type-casted as string, resulting an empty string, not what you would expect.
According to the documentation:
Returns the escaped string, or FALSE on error.
A MySQL connection is required before using mysql_real_escape_string() otherwise an error of level E_WARNING is generated, and FALSE is returned. If link_identifier isn't defined, the last MySQL connection is used.
The warning is good if you go in the logs to see what was happened, but would not prevent it from happening.
I know that there are very little changes to fail, but if there is at least one change it should be expected by your application.
This function will fail if:
developer did not connect to the database before calling this function
the connection to the database failed before calling this function
the memory of the server (where mysql client resides) is low and cannot copy the string for escaping
...
This is an exemple of "normal" usage:
$db = mysql_connect() or die('Cannot connect to database');
$value = mysql_real_escape_string($_POST['value'], $db);
mysql_query('insert into tablex (value) values ("'.$value.'")', $db) or die('Cannot insert data in database');
I am using something like this (in am OO wrapper for mysql):
class mywrapper{
// ... [code ...]
// $this->db is the mysql link identifier
public function escape($string)
{
if(mysql_real_escape_string($string, $this->db) === false)
{
throw new Exception('Some message');
}
}
} // end class
// I'm calling it as
// $myWrapper->insert('insert into tablex (value) values ("'.($myWrapper->escape($value)).'")');
This will throw an exception that will be capture by the exception handler, and most important I prevented the insertion of false positive values in the database, ensuring data consistency.
I am missing something ? I am playing safe or I am beeing paranoic ? :)
In a sense you are missing something as it's no longer recommended to use the mysql_ family of functions. Instead use mysqli or PDO. Both of these provide parameterised queries which will automatically escape your input data for you.
No, I don't think you're being paranoid. (or we're both paranoid)
I do think too that it's definitely a good practice to avoid sending nothing in a mysql query (pretty much as you wouldn't want to send a nothing valued $_POST variable).
I noted the problems you mentioned:
This is an exemple of "normal" usage:
$db = mysql_connect();
Well, at this point you should definitely check that the connection succeeded.. Also, with a good database abstraction layer you can prevent that the user "forgot" to connect to the database (because he never has to do that manually). (1).
If you lose connection in the meantime, then your query will fail, so it doesn't matter what you've sent (2).
mysql_real_escape_string is done at client side, so memory usage of mysql server is not an issue (3).

Insert blob data into mysql using MDB2 in php

Can anybody help me to insert blob data in Mysql using MDB2 through php ?
I want to insert file into database using MDB2.
MBD2 setup is works fine.
This may help, as I had trouble with this for anyone in the future, note the quote sets the 'blob' type when sprintf injected each string generated by the quote functions. The key part appears to be using "file://" with a reference to a file for it to work this way.
$database is a mdb2 object as typically given in other examples online.
// NOTE BELOW: The quote function or lower layers - requires the file reference as below
// I could not pass the raw bytes through that were in a variable for some reason, as the
// quote method appeared to modify the bytes - maybe as it assumes a charset?
$sql = 'UPDATE %s SET %s=%s WHERE iconid=%d';
$sql = sprintf ($sql,
$database->quoteIdentifier('chanicon'),
$database->quoteIdentifier('icondata'),
$database->quote("file://".$_FILES['userfile']['tmp_name'][0], 'blob'),
$database->quote($_REQUEST['iconid'], 'integer')
);

mysql_query function in php

<?php
$con= mysql_connect("localhost","root","mysql");
mysql_select_db("Db_name",$con);
$res=mysql_query("select *from table_name");
mysql_close($con); // closing connection before fetching contents.
while($r=mysql_fetch_array($res)) {
echo $r['ename'];
}
?>
This programs works even if i close the connection before fetching contents from the table.
In order get table contents from the $res connection is not necessary ?
Is$res just a program variable ? If so what kind of data structure it is using(associative array ? )
In oracle we have implicit cursor and explicit cursor. Are there any equivalent things in mysql?
In the above program where cursors come into picture ?
$res in your case is a special type called a "Resource". Simply put it is a collection of the data returned which the mysql_fetch_* functions operate. As such, it can live beyond the connection. Check the documentation for more details.
The MySQL client library will fetch the whole result set before the call to mysql_query() returns which explains why your code works.
You can use mysql_unbuffered_query() to fetch the rows incrementally in which case you must keep the connection open.
Note that fetching the rows is handled inside the MySQL client code. $res is just an opaque ressource type that represents an internal resultset object (buffered or not). You can only operate on that ressource by passing it to other MySQL functions.
In order get table contents from the $res connection is not necessary ?
Why did not you try it and see?
Anyway, what is the reason to close connection manually?
Is $res just a program varible ? If so what kind of data structure it is using(associative array ?
Yes, it is a variable. You can see what is inside with var_dump($res);
In oracle we have implicit cursor and explicit cursor.Are there any equivalent things in mysql ?
In the above program where cursors come into picture ?
What exact task are you trying to solve?
As jason said $res is just like a normal variable of type Resource. This variable holds its value even after the mysql connection is closed as it has no connection with the mysql connection.

Categories