php is about to stop support for mysql functions, and there are lots of tools/recommendations for how to upgrade to upgrade to mysqli from mysql. I came up with this design, and I wonder if there are any issues that my solutions can have:
Create a file called translate.php and require_once it in all php files that use any mysql functions.
Create global variable in that file and call it $_CONN
overwrite default mysql function with the following (using overwrite_function which is not shown here)
$_CONN;
mysql_query($q)
{mysqli_query($_CONN,$q);}
mysql_error()
{mysqli_error($_CONN);}
mysql_connect($h,$u,$p)
{$_CONN=mysqli_connect($h,$u,$p);}
mysql_fetch_assoc($r)
{mysqli_fetch_assoc($r);}
mysql_fetch_array($r)
{mysqli_fetch_array($r);}
Are there any issues with my solution?
To move from mysql to mysqli in a painless way you have to move towards PDO
Related
I am using the below code to connect to the database in the module to write the several database queries which are not correct it seems, so please tell me what is the correct way of connecting to the database from the new module.
$con = mysql_connect(_DB_SERVER_, _DB_USER_, _DB_PASSWD_);
mysql_select_db(_DB_NAME_);
use
$query ="select * from name_table"; /*example query*/
Db::getInstance()->executeS($query);
you do not need anything else to make a query
Please, before read this guidelines to create a new module: How to create a module
And then this: Best practices of the Db Class
Including the files like the elPresta says it's old and deprecated method, after that to make a simple query, read what he wrote Matteo Enna.
Just include these files and thats it!
include(dirname(__FILE__).'/../../config/config.inc.php');
include(dirname(__FILE__).'/../../init.php');
And after all you can use methods as Matteo told u. Or read more here ( http://doc.prestashop.com/display/PS15/DB+class+best+practices )
I have developed a project under which several sql query have been used. Now I want to monitor some query in order increase security. So I want every query to be passed through a function first. As there are too many queries so I can not go back and edit every file and query. Is there a way that I can trap into queries before they are sent to mysql server?
There are four ways to accomplish this depending on what you are using, the last being the much more reliable.
The General Query Log
MySQL provides a mechanism to log just about everything that the mysqld process is doing, via the general query log. As you described in your question you probably do not have persistent connections, so you will need to either:
Enable the MySQL general query log when the mysqld process is started, with the --log[=file_name]
Set a global/session variable with SET GLOBAL general_log = 'ON'.
Fore more information about the general query log, see the MySQL 5.1 reference manual.
Using sed (or manually!)
This technique involves creating a a new function, and renaming all of the mysqli_* function calls to call another function.
Presuming your newly created function is named proxy_query(), you can use sed to traverse through all files and change them automatically:
sed i '.bck' 's/mysqli_query/proxy_query/'
The -i paramater specifies that the file should be edited in place, and that a copy should be made of the original file and have a .bck extension appended.
The runkit extension
I must admit that I'm being naive here, and that I haven't used this particular extension before - but it is possible to rename functions with this PECL extension.
The requirements for this extension can be found here, and note that it is not bundled with PHP.
As with above, you can create a proxy function where all calls will go through. Let's assume it's also called proxy_query. Usage would go something like this:
// rename the function (a very bad idea, really!)
runkit_function_renam('mysqli_connect', 'proxy_super');
function mysqli_query($query, $resultmode = MYSQLI_STORE_RESULT)
{
// do something with the SQL in $query
// .. and call mysqli_query, now proxy_super
return proxy_super($query, $resultmode);
}
I have to note here that this method is highly discouraged. You shouldn't ever need to set default PHP functions.
Using Pdo/OO-mysqli
This is the simplest technique, and probably the most reliable as well. If you're using Pdo already, you can simply extend the \Pdo class. A similar approach could be used with MySQL Improved(mysqli):
class MyPdo extends \Pdo
{
public function query($query [, ... ])
{
// do something with $query
return parent::query($query [, ... ]);
}
}
Also note here, that this will only work if you are using Pdo, and if you are able to change the instantiation of the Pdo object, to overwrite it to your own class: MyPdo.
For more information about the \Pdo class, and it's children, see the manual.
If you want to monitor incoming queries using SQL profiler can be an excellent way to gather information on what's going on inside SQL without passing it all through a single function or procedure.
So I'm confident that the stored procedure works, I've tested it in SQL Server Management Studio just fine and it runs in other service instances. The query used to run this SP follows;
exec sp_getAgentCommissionDetails_v3 201000023762230, 5
So it runs fine on SSMS and under the old MSSQL driver. But I run the query with SQLSRV like so;
function mssql_query($string, $linkID = null, $batch = 0) {
if (!$linkID) {
global $dbhandle;
$linkID = $dbhandle;
}
// SQLSRV_CURSOR_KEYSET ensures mssql_num_rows() works in most cases. Default scrollablility does not support this.
return sqlsrv_query($linkID, $string, array(), array("Scrollable" => SQLSRV_CURSOR_KEYSET));
}
The function is named mssql_query because we're updating an old system from MSSQL to SQLSRV, but we're working with an extremely messy old system. So rather than trying to refactor it we're overwriting the MSSQL_query function (having disabled the mssql extension) with one that uses SQLSRV.
$dbhandle is our SQLSRV connection resource. Other queries run just fine using this method.
So my question- is there any reason the query to run a stored procedure would not run under this SQLSRV function?
Couple notes on my troubleshooting;
I'm aware SQLSRV and PDO have a specific method to run stored procedures. Using that is not an option due to the massive codebase that uses the method above in various places and because we haven't got the man hours to refactor every page.
I pulled up SQLSRV_errors() and it returned 'Executing SQL directly; no cursor'. After a bit of research this seems to be a bug in the driver that returns this generic error message instead of a more specific useful one, so it can mean very many things.
There are no cursors or loops involved in the stored procedure.
Found a solution to this. SQLSRV seems to by default treat warnings as errors. Fixed this with a config change in the connection file;
sqlsrv_configure("WarningsReturnAsErrors",0);
It now runs fine.
As I know PDO support has been added to codeigniter recently but I can't find any documentation or tutorial about how to actually use it. Can anyone tell how can I use it?
You can edit /application/config/database.php and to enable the PDO driver:
$db['default']['hostname'] = 'pgsql:localhost';
// or mysql:localhost
// or sqlite::memory:
$db['default']['dbdriver'] = 'pdo';
If you want to directly get you hand on the active DB connection. This might work, but I am not CI developer .. so no guarantees. I tried to understand that brain rotting code, but i suspect, that i failed. I'm not good at PHP4 + eval():
$CI = get_instance();
var_dump($CI->db->conn_id);
// should show that conn_id is instance of PDO
Well, since CodeIgniter is merely a PHP framework, nothing prevents you from using it natively, as in $pdo = new PDO(...);.
However, when they say PDO is now supported, I think they mean their normal Database class now uses PDO (rather than MySQLi or the such).
How can I detect, using php, if the machine has oracle (oci8 and/or pdo_oci) installed?
I'm working on a PHP project where some developers, such as myself, have it installed, but there's little need for the themers to have it. How can I write a quick function to use in the code so that my themers are able to work on the look of the site without having it crash on them?
if the oci extension isn't installed, then you'll get a fatal error with farside.myopenid.com's answer, you can use function_exists('oci_connect') or extension_loaded('oci8') (or whatever the extension's actually called)
The folks here have pieces of the solution, but let's roll it all into one solution.
For just a single instance of an oracle function, testing with function_exists() is good enough; but if the code is sprinkled throughout to OCI calls, it's going to be a huge pain in the ass to wrap every one in a function_exists() test.
Therefore, I think the simplest solution would be to create a file called nodatabase.php that might look something like this:
<?php
// nodatabase.php
// explicitly override database functions with empty stubs. Only include this file
// when you want to run the code without an actual database backend. Any database-
// related functions used in the codebase must be included below.
function oci_connect($user, $password, $db = '', $charset='UTF-8', $session_mode=null)
{
}
function oci_execute($statement, $mode=0)
{
}
// and so on...
Then, conditionally include this file if a global (say, THEME_TESTING) is defined just ahead of where the database code is called. Such an include might look like this:
// define("THEME_TESTING", true) // uncomment this line to disable database usage
if( defined(THEME_TESTING) )
include('nodatabase.php'); // override oracle API with stub functions for the artists.
Now, when you hand the project over to the artists, they simply need to make that one modification and they're good to go.
I dont know if I fully understand your question but a simple way would be to do this:
<?php
$connection = oci_connect('username', 'password', 'table');
if (!$connection) {
// no OCI connection.
}
?>
As mentioned above by Greg, programmatically you can use the function_exists() method. Don't forget you can also use the following to see all the environment specifics with your PHP install using the following:
<?php
phpinfo();
?>