Extending mysqli classes

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Alkis
Forum Commoner
Posts: 31
Joined: Fri Mar 26, 2010 8:41 am

Extending mysqli classes

Post 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?
zerkig
Forum Newbie
Posts: 10
Joined: Fri Mar 26, 2010 1:44 am

Re: Extending mysqli classes

Post 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();
 
?>
 
Last edited by Benjamin on Fri Mar 26, 2010 9:00 pm, edited 1 time in total.
Reason: Changed code type from text to php
Alkis
Forum Commoner
Posts: 31
Joined: Fri Mar 26, 2010 8:41 am

Re: Extending mysqli classes

Post 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.
zerkig
Forum Newbie
Posts: 10
Joined: Fri Mar 26, 2010 1:44 am

Re: Extending mysqli classes

Post 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.
Alkis
Forum Commoner
Posts: 31
Joined: Fri Mar 26, 2010 8:41 am

Re: Extending mysqli classes

Post 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.
zerkig
Forum Newbie
Posts: 10
Joined: Fri Mar 26, 2010 1:44 am

Re: Extending mysqli classes

Post 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?
Post Reply