Объекты данных PHP

Коментарии

If your having problems re-compiling PHP with PDO as shared module try this.

--enable-pdo=shared
--with-pdo-mysql=shared,/usr/local/mysql
--with-sqlite=shared
--with-pdo-sqlite=shared

1. If PDO is built as a shared modules, all PDO drivers must also be
built as shared modules.
2. If ext/pdo_sqlite is built as a shared module, ext/sqlite must also
be built as a shared module.
3. In the extensions entries, if ext/pdo_sqlite is built as a shared
module, php.ini must specify pdo_sqlite first, followed by sqlite.
2006-02-07 20:18:50
http://php5.kiev.ua/manual/ru/book.pdo.html
Автор:
Below is an example of extending PDO & PDOStatement classes:

<?php

class Database extends PDO
{
    function 
__construct()
    {
       
parent::__construct('mysql:dbname=test;host=localhost''root''');
       
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement', array($this)));
    }
}

class 
DBStatement extends PDOStatement
{
    public 
$dbh;

    protected function 
__construct($dbh)
    {
       
$this->dbh $dbh;
       
$this->setFetchMode(PDO::FETCH_OBJ);
    }
   
    public function 
foundRows()
    {
       
$rows $this->dbh->prepare('SELECT found_rows() AS rows', array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE));
       
$rows->execute();
       
$rowsCount $rows->fetch(PDO::FETCH_OBJ)->rows;
       
$rows->closeCursor();
        return 
$rowsCount;
    }
}

?>
2006-02-19 12:16:04
http://php5.kiev.ua/manual/ru/book.pdo.html
I wanted to extend PDO class to store statistics of DB usage, and I faced some problems. I wanted to count number of created statements and number of their executings. So PDOStatement should have link to PDO that created it and stores the statistical info. The problem was that I didn't knew how PDO creates PDOStatement (constructor parameters and so on), so I have created these two classes:

<?php
/**
 * PHP Document Object plus
 * 
 * PHP Document Object plus is library with functionality of PDO, entirely written
 * in PHP, so that developer can easily extend it's classes with specific functionality,
 * such as providing database usage statistics implemented in v1.0b
 * 
 * @author Peter Pokojny
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */
   
class PDOp {
        protected 
$PDO;
        public 
$numExecutes;
        public 
$numStatements;
        public function 
__construct($dsn$user=NULL$pass=NULL$driver_options=NULL) {
           
$this->PDO = new PDO($dsn$user$pass$driver_options);
           
$this->numExecutes 0;
           
$this->numStatements 0;
        }
        public function 
__call($func$args) {
            return 
call_user_func_array(array(&$this->PDO$func), $args);
        }
        public function 
prepare() {
           
$this->numStatements++;
           
           
$args func_get_args();
           
$PDOS call_user_func_array(array(&$this->PDO'prepare'), $args);
           
            return new 
PDOpStatement($this$PDOS);
        }
        public function 
query() {
           
$this->numExecutes++;
           
$this->numStatements++;
           
           
$args func_get_args();
           
$PDOS call_user_func_array(array(&$this->PDO'query'), $args);
           
            return new 
PDOpStatement($this$PDOS);
        }
        public function 
exec() {
           
$this->numExecutes++;
           
           
$args func_get_args();
            return 
call_user_func_array(array(&$this->PDO'exec'), $args);
        }
    }
    class 
PDOpStatement implements IteratorAggregate {
        protected 
$PDOS;
        protected 
$PDOp;
        public function 
__construct($PDOp$PDOS) {
           
$this->PDOp $PDOp;
           
$this->PDOS $PDOS;
        }
        public function 
__call($func$args) {
            return 
call_user_func_array(array(&$this->PDOS$func), $args);
        }
        public function 
bindColumn($column, &$param$type=NULL) {
            if (
$type === NULL)
               
$this->PDOS->bindColumn($column$param);
            else
               
$this->PDOS->bindColumn($column$param$type);
        }
        public function 
bindParam($column, &$param$type=NULL) {
            if (
$type === NULL)
               
$this->PDOS->bindParam($column$param);
            else
               
$this->PDOS->bindParam($column$param$type);
        }
        public function 
execute() {
           
$this->PDOp->numExecutes++;
           
$args func_get_args();
            return 
call_user_func_array(array(&$this->PDOS'execute'), $args);
        }
        public function 
__get($property) {
            return 
$this->PDOS->$property;
        }
        public function 
getIterator() {
            return 
$this->PDOS;
        }
   }
?>

Classes have properties with original PDO and PDOStatement objects, which are providing the functionality to PDOp and PDOpStatement.
From outside, PDOp and PDOpStatement look like PDO and PDOStatement, but also are providing wanted info.
2006-04-23 11:50:58
http://php5.kiev.ua/manual/ru/book.pdo.html
If you need to get Output variable from MSSQL stored procedure, try this :

-- PROCEDURE
CREATE PROCEDURE spReturn_Int @err int OUTPUT 
AS
SET @err = 11
GO

$sth = $dbh->prepare("EXECUTE spReturn_Int ?");
$sth->bindParam(1, $return_value, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT);
$sth->execute();
print "procedure returned $return_value\n";
2006-07-25 11:42:58
http://php5.kiev.ua/manual/ru/book.pdo.html
Please note this:

Won't work:
$sth = $dbh->prepare('SELECT name, colour, calories FROM ?  WHERE calories < ?');

THIS WORKS!
$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < ?');

The parameter cannot be applied on table names!!
2006-08-30 17:56:04
http://php5.kiev.ua/manual/ru/book.pdo.html
If you use $dbh = new PDO('pgsql:host=localhost;dbname=test_basic01', $user, $pass); and you get the following error:
PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[08006] [7] could not connect to server: Connection refused\n\tIs the server running on host "localhost" and accepting\n\tTCP/IP connections on port 5432?'
then as pointed out under pg_connect at: function.pg-connect#38291 
******
you should try to leave the host= and port= parts out of the connection string. This sounds strange, but this is an "option" of Postgre. If you have not activated the TCP/IP port in postgresql.conf then postgresql doesn't accept any incoming requests from an TCP/IP port. If you use host= in your connection string you are going to connect to Postgre via TCP/IP, so that's not going to work. If you leave the host= part out of your connection string you connect to Postgre via the Unix domain sockets, which is faster and more secure, but you can't connect with the database via any other PC as the localhost.
******
Sincerely,
Aouie
2006-09-28 02:38:02
http://php5.kiev.ua/manual/ru/book.pdo.html
It seems MySQL doesn't support scrollable cursors. So unfortunately PDO::CURSOR_SCROLL wont work.
2007-05-23 10:57:00
http://php5.kiev.ua/manual/ru/book.pdo.html
Not all PDO drivers return a LOB as a file stream; mysql 5 is one example. Therefore when streaming a mime typed object from the database you cannot use fpassthru.

The following is a modified example that works with a mysql database. (Tested FreeBSD v 6.2 with mysql 5.0.45 and php 5.2.3) 

<?php
ob_start
();
$db = new PDO('mysql:host=localhost;dbname=<SOMEDB>''<USERNAME>''PASSWORD');
$stmt $db->prepare("select contenttype, imagedata from images where id=?");
$stmt->execute(array($_GET['id']));
$stmt->bindColumn(1$typePDO::PARAM_STR256);
$stmt->bindColumn(2$lobPDO::PARAM_LOB);
$stmt->fetch(PDO::FETCH_BOUND);
ob_clean();
header("Content-Type: $type");
echo 
$lob// fpassthru reports an error that $lob is not a stream so echo is used in place.
ob_end_flush();
?>

Please note the inclusion of buffer control. I only needed this when using 'include','include_once','require', or 'require_once' - my feeling is there is a subtle issue with those options as even an empty include file caused a buffer issue for me. === AND YES, I DID CHECK MY INCLUDE FILES DID NOT HAVE SPURIOUS WHITESPACE ETC OUTSIDE THE <?php ?> DELIMITERS! ===
2007-09-02 15:12:59
http://php5.kiev.ua/manual/ru/book.pdo.html
Example 5: 
<?php
try {
 
$dbh = new PDO('odbc:SAMPLE''db2inst1''ibmdb2',
      array(
PDO::ATTR_PERSISTENT => true));
....... 
} catch (
Exception $e) {
 
$dbh->rollBack();
  echo 
"Failed: " $e->getMessage();
}
?> 

We must change the last two lines to catch the error connecting to the database:

} catch (Exception $e) {
  echo "Failed: " . $e->getMessage();
  $dbh->rollBack();
}
?>
2007-10-16 11:34:21
http://php5.kiev.ua/manual/ru/book.pdo.html
If you will make a OBJ row from PDO you can use this eg.

$resKampange = $dbc->prepare( "SELECT * FROM Table LIMIT 1" );
$resKampange->execute();
$rowKampange = $resKampange->fetch( PDO::FETCH_OB );

echo $rowKampange->felt1;

Good lock :0)
2007-12-10 06:29:51
http://php5.kiev.ua/manual/ru/book.pdo.html
This works to get UTF8 data from MSSQL:

<?php
$db 
= new PDO('dblib:host=your_hostname;dbname=your_db;charset=UTF-8'$user$pass);
?>
2010-06-29 12:38:33
http://php5.kiev.ua/manual/ru/book.pdo.html
You may also have to edit /etc/freetds.conf. Make sure the TDS version is recent, e.g., "tds version = 8.0".
2011-01-04 09:25:38
http://php5.kiev.ua/manual/ru/book.pdo.html
Автор:
Merge the prepare() and execute() in one function like a sprintf().
And like sprintf, I choose to use unnamed args (?) ;)

you could still use old insecure query() ( not prepared ) with renamed function :)

<?php
class MyPDO extends PDO{

    const 
PARAM_host='localhost';
    const 
PARAM_port='3306';
    const 
PARAM_db_name='test';
    const 
PARAM_user='root';
    const 
PARAM_db_pass='';

    public function 
__construct($options=null){
       
parent::__construct('mysql:host='.MyPDO::PARAM_host.';port='.MyPDO::PARAM_port.';dbname='.MyPDO::PARAM_db_name,
MyPDO::PARAM_user,
MyPDO::PARAM_db_pass,$options);
    }

    public function 
query($query){ //secured query with prepare and execute
       
$args func_get_args();
       
array_shift($args); //first element is not an argument but the query itself, should removed

       
$reponse parent::prepare($query);
       
$reponse->execute($args);
        return 
$reponse;

    }

    public function 
insecureQuery($query){ //you can use the old query at your risk ;) and should use secure quote() function with it
       
return parent::query($query);
    }

}

$db = new MyPDO();
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODEPDO::FETCH_OBJ);

$t1 = isset($_GET["t1"])?$_GET["t1"]:1// need to be securised for injonction
$t2 = isset($_GET["t2"])?$_GET["t2"]:2// need to be securised for injonction
$t3 = isset($_GET["t3"])?$_GET["t3"]:3// need to be securised for injonction

$ret $db->query("SELECT * FROM table_test WHERE t1=? AND t2=? AND t3=?",$t1,$t2,$t3);
//$ret = $db->insecureQuery("SELECT * FROM table_test WHERE t1=".$db->quote($t1));

while ($o $ret->fetch())
{
    echo 
$o->nom.PHP_EOL;
}
?>
2013-07-08 13:19:25
http://php5.kiev.ua/manual/ru/book.pdo.html
When using prepared statements there is no official PDO feature to show you the final query string that is submitted to a database complete with the parameters you passed.

Use this simple function for debugging. The values you are passing may not be what you expect.

<?php
//Sample query string
$query "UPDATE users SET name = :user_name WHERE id = :user_id";

//Sample parameters
$params = [':user_name' => 'foobear'':user_id' => 1001];

function 
build_pdo_query($string$array) {
   
//Get the key lengths for each of the array elements.
   
$keys array_map('strlen'array_keys($array));

   
//Sort the array by string length so the longest strings are replaced first.
   
array_multisort($keysSORT_DESC$array);

    foreach(
$array as $k => $v) {
       
//Quote non-numeric values.
       
$replacement is_numeric($v) ? $v "'{$v}'";

       
//Replace the needle.
       
$string str_replace($k$replacement$string);
    }

    return 
$string;
}

echo 
build_pdo_query($query$params);    //UPDATE users SET name = 'foobear' WHERE id = 1001
?>
2014-05-08 02:31:23
http://php5.kiev.ua/manual/ru/book.pdo.html
This is a little late... but I'm old and slow.......
Regarding Extending PDOStatement and PDO I found that sending the PDOExtended class by reference helps:
    In the constructor after parent::__construct() :
$this->setAttribute(\PDO::ATTR_STATEMENT_CLASS,array('PDOStatementExtended', [&$this]));}

And in 
class PDOStatementExtended extends \PDOStatement
{
 
  protected function __construct
  (
    \PDO &$PDO,
   )
2021-02-17 16:12:13
http://php5.kiev.ua/manual/ru/book.pdo.html

    Поддержать сайт на родительском проекте КГБ