Page 1 of 1
Extending mysqli classes
Posted: Fri Mar 26, 2010 8:52 am
by Alkis
I am trying to extend the MySQLi php core classes to add extra functionality to my code. I Successfully extended MySQLi::prepare() and MySQLi::query() methods after finding what is that exactly happends in those methods.
So I have extended the MySQLi class to my own DBConnection class, MySQLi_STMT to my DBStatement class, and MySQLi_Result class to my own DBResult class.
What I couldn't figure out is how to override the MySQLi::store_result, MySQLi::use_result, MySQLi_STMT::result_metadata and MySQLi_STMT::store_result to return my custom DBResult object instead of the core MySQLi_Result one, because I can't find what is happening on the inside of these methods in order to achieve the same functionality.
Any help on this?
Re: Extending mysqli classes
Posted: Fri Mar 26, 2010 3:49 pm
by zerkig
The point about OO design is that when you extend a class you don't care what the parent class is doing you just add your own functionality and let the parent take care of itself
e.g.
Code: Select all
<?php
class zerkig_connection extends MySQLi
{
public function __construct()
{
// override constructor to connect to specific db
// TODO overide the mysqli methods that allow a db/conection change
parent::__construct("localhost","root","mypassword","information_schema");
}
private static function zerkig_sql_sanatizer ( $query)
{
//should probably
//check for sql injection nasties
// but for now just return an innocuous query
return "SELECT * FROM character_sets";
}
public function prepare ( $query )
{
return parent::prepare( $this->zerkig_sql_sanatizer($query) );
}
public function query ( $query )
{
return parent::query ( $this->zerkig_sql_sanatizer($query) );
}
public function __destruct()
{
// if your code has open any files/connections etc
// try and close them here
// it is always a good idea to call my parent's destructor
// but it does not exist at the moment
// parent::__destruct();
}
}
$mysqli = new zerkig_connection();
if ($result = $mysqli->query("select * from sopmewhere")) {
echo "num rows".$result->num_rows." . </br />";
while ($row = $result->fetch_object()) {
echo "desc: ".$row->DESCRIPTION." </br />";
}
} else {
echo $mysqli->error;
}
$mysqli->close();
?>
Re: Extending mysqli classes
Posted: Fri Mar 26, 2010 8:29 pm
by Alkis
I am working with oop for more than 10 years. This is not what I actually asked.
Please read carefully what I want to achieve.
Thanks for your effort but it is off subject.
Re: Extending mysqli classes
Posted: Sat Mar 27, 2010 6:56 am
by zerkig
Sorry if I caused any annoyance
Ok let's try again. You say you can't find out whats going on in MySQLi::store_result among others.
Is this part of the answer you're looking for ( from php 5.3.2 source ext/mysqli/mysqli_api.c)
Code: Select all
/* {{{ proto object mysqli_store_result(object link)
Buffer result set on client */
PHP_FUNCTION(mysqli_store_result)
{
MY_MYSQL *mysql;
MYSQL_RES *result;
zval *mysql_link;
MYSQLI_RESOURCE *mysqli_resource;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
if (!(result = mysql_store_result(mysql->mysql))) {
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
RETURN_FALSE;
}
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);
}
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)result;
mysqli_resource->status = MYSQLI_STATUS_VALID;
MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
}
/* }}} */
or is it that you can't figure out what this is doing?
Actually I am going to be little help on this, the method appears to be allocating resources on the client to handle the transfer of the result set with a lot of attention paid to BLOBs but my C is not that good.
Re: Extending mysqli classes
Posted: Sat Mar 27, 2010 12:53 pm
by Alkis
First of all sorry for my not so kind answer before. Lots on my mind these days.
Well,
Extending the MySQLi class, I have already overridden its query and prepare methods, by finding how to simulate their functionality using php, without calling their parent methods.
So I override the query() method to return my DBResult object ( which is a class extending MySQLi_Result class), in place of the core query() one which returned a MySQLi_Result object.
And I did the same for the prepare() method. (My overriden method returns my DBStatement object, which extends the MySQLi_STMT class).
But I cannot find a way of overriding/replacing the store_result() and use_result() methods as I did with the above.
So to put it more simply:
lets say that the store_result and use_result methods did not exist, and you invented them, how would you do it with php?
That's what I cannot find. Trying to find the same for the MySQLi_STMT::result_metadata also.
Thank you very much again for your help.
Re: Extending mysqli classes
Posted: Sun Mar 28, 2010 9:10 am
by zerkig
Stupid question again:
If you have already implemented Query()
Functionally, using this function is identical to calling mysqli_real_query followed either by mysqli_use_result or mysqli_store_result.
from
mysql manual
why don't you override mysqli_real_query with a call to your query() and overide store_result() just to return your DBResult object or false
from
php manual
You must call mysqli_stmt_store_result() for every query that successfully produces a result set (SELECT, SHOW, DESCRIBE, EXPLAIN), and only if you want to buffer the complete result set by the client, so that the subsequent mysqli_stmt_fetch() call returns buffered data.
Returns a buffered result object or FALSE if an error occurred.
***false as well for no result set e.g. INSERT
and do the same for use_result?