I have an open SQL Server connection and need to open and close another while maintaining the first connection. I CANNOT hold onto the resource ID for the original.
Connection A (may or may not be open)
Open connection B
Perform a few queries using connection B
Close connection B
Continue working with connection A
If you are using the below method to establish your connections you may not really have an 'A' and 'B' connection. It may also provide a way for you to recover the previously opened 'A' connection if you utilize the '$new_link' argument.
resource mssql_connect ([ string $servername [, string $username [, string $password [, bool $new_link ]]]] )
from php.net http://www.php.net/manual/en/function.mssql-connect.php
new_link
If a second call is made to mssql_connect() with the same arguments, no new link will be established, but instead, the link identifier of the already opened link will be returned. This parameter modifies this behavior and makes mssql_connect() always open a new link, even if mssql_connect() was called before with the same parameters.
So basically if you create connection A and then connection B with new_link true then use and close connection B, your next call to mssql_connect with new_link false would return connection A.
I have not tested this but the documentation shows it to be possible and though it is probably not ment to solve your problem you may be able to use it for that.
I am however curious why you can not hold onto A as well as why you need the second connection.
Related
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.
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.
I have marked many of developers using
$con1 = mysql_connect('localhost', 'username', 'password');
$rv1 = mysql_select_db('db1'); // not added connection
Instead
$con1 = mysql_connect('localhost', 'username', 'password');
$rv1 = mysql_select_db('db1', $con1); // added connection
Can I know the difference between this both?
Actually this both are giving same result
The mysql_ functions will implicitly use the last connection which was opened with mysql_connect, if you do not pass an explicit connection parameter. So, yes, in this case it's the same result whether you pass the parameter or not. You will get different results should you happen to open more than one connection using mysql_connect.
Note that implicitly relying on an open connection is bad practice, precisely because your application will screw up if you need to open more connections sometime later. Also note that the mysql_ API is dead, switch to mysqli or PDO.
Take a look at the PHP manual:
http://www.php.net/manual/en/function.mysql-select-db.php
Without a link identifier, mysql_select_db will use the last connection opened with mysql_connect or it will try to connect without any parameter. So the second one is safer and you could use multiple connections.
mysql_select_db and mysql_connect is deprecated though. You should switch to PDO or mysqli.
Taken from the documentation:
bool mysql_select_db ( string $database_name [, resource $link_identifier = NULL ] )
link_identifier
The MySQL connection. If the link identifier is not specified, the last link opened by mysql_connect() is assumed. If no such link is found, it will try to create one as if mysql_connect() was called with no arguments. If no connection is found or established, an E_WARNING level error is generated.
Basically it will used the last known connection object if none is provided. In your case, the last known connection was created on the previous line. This is an optional parameter so the function will operate in the same way if the connection is passed explicitly or not.
On a related note, please notice the big red warning at the top of the documentation page I have linked to. The mysql_* extensions are deprecated and it is recommended that you use a different extension. For a more detailed explanation, please take a look at this thread:
Why shouldn't I use mysql_* functions in PHP?
What are the differences between the following:
// Persistent connection
$mysqli->real_connect("p:" . $host, $user, $pass, $db, null, null, 0);
and
// Interactive connection
$mysqli->real_connect($host, $user, $pass, $db, null, null, MYSQLI_CLIENT_INTERACTIVE);
or even this one...
// Interactive AND persistent
$mysqli->real_connect("p:" . $host, $user, $pass, $db, null, null, MYSQLI_CLIENT_INTERACTIVE);
Just my interpretation of the docs...
Persistent connections are kept open indefinitely. Non-persistent connections are not.
The mysql_pconnect() docs are a little more clear than the real_connect() docs:
mysql_pconnect() acts very much like mysql_connect() with two major differences.
First, when connecting, the function would first try to find a (persistent) link that's already open with the same host, username and password. If one is found, an identifier for it will be returned instead of opening a new connection.
Second, the connection to the SQL server will not be closed when the execution of the script ends. Instead, the link will remain open for future use ( mysql_close() will not close links established by mysql_pconnect()).
This type of link is therefore called 'persistent'.
Regarding MYSQLI_CLIENT_INTERACTIVE:
MYSQLI_CLIENT_INTERACTIVE
Allow interactive_timeout seconds (instead of wait_timeout seconds) of inactivity before closing the connection. The client's session wait_timeout variable will be set to the value of the session interactive_timeout variable.
Normally, non-persistent connections are closed after the number of seconds specified by the wait_timeout variable. With this flag, they are instead closed after the number of seconds specified by the interactive_timeout variable.
By my interpretation, that means that the MYSQLI_CLIENT_INTERACTIVE does not change the behavior of a persistent connection.
When you use the first one mysqli tries to find a (persistent) link that's already open with the same host, username and password (NOT PORT). If one is found, an identifier for it will be returned instead of opening a new connection.
The connection to the SQL server will NOT be closed when the execution of the script ends. Instead, the link will remain open for future use.
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).