Jump to content
Larry Ullman's Book Forums

sendy

Members
  • Posts

    13
  • Joined

  • Last visited

Posts posted by sendy

  1. Hi guys, i read about PDO in the book, then i read some PDO articles..

    Most of the articles say that we should turn off PDO::ATTR_EMULATE_PREPARES if using MYSQL latest driver.. is this true?

     

    i searched some explanation why with recent mysql i should turn of PDO::ATTR_EMULATE_PREPARES, but unfortunately my newbie brain doesn't understand their explanation...

     

    all i know is PDO will send the query to the MYSQL when we use :

     

    $stmt = $pdo->prepare('query');
     

     

     

    then PDO will send the data(placeholder's value) :

     

    $stmt->bindValue(':val', $value, PDO::PARAM_STR);
    $stmt->execute();
     

     

     

    my mysql version :  5.x

    php version : 5.4

     

    please guide me here , if possible with example codes

  2. SOLVED


    sorry guys my mistake actually its a pretty easy answer why  MySessionHandler  class doesnt produce error wihtout session_write_close() in the end of script, 

    session_set_save_handler() by default will register session_write_close() to register_shutdown_function()

    so if u want to make your own shutdown function for session then use :

     

    session_set_save_handler($SessionClass, FALSE)
     

     

    if u do this then u must provide session_write_close() in your class destructor

    source : http://php.net/manual/en/function.session-set-save-handler.php

    thank you Larry for the support

  3. Have you confirmed whether the changes are written to the session (the database) or not?

     

    yes i have , its written in database using pdo and its even success accessing db session(using pdo) in the next browser request

     

    i added

     

    if($_SERVER['REQUEST_METHOD'] == 'POST')
    {
        $_SESSION['post_data'] = $_POST['post_data'];
    }
    
    <form action="session_link.php" method="post">
        <input type="text" name="post_data" />
        <input type="submit" name="submit" value="store data" />
        
    </form>
     

     

    and confirmed that MySessionHandler() success storing the session data from $_POST method to the database

  4. im still newbie and i dont know much, but from what i know ,

     

    protected static function instantiate($record) {
            $object = new self;
            foreach ($record as $attribute=>$value) {
                if ($object->has_attribute($attribute)){
                    $object->attribute = $value;
                }
            }
            return $object;
        }
     

     

    new self() will return the class that has define the method(even if u call Photograph::instantiate()) which is your DatabaseObject.

     

    then in that code, u try to do :

     

     $object->attribute = $value 
    /*  $object is instance of DatabaseObject because of the new self() , and because of that, it doesn't have the attribute u need..  */
     
    

     

    its like this case :

     

     

    class ParentObject
    {
        protected static function getObject()
        {
            return new self();
        }
    }
    
    class ChildObject extends ParentObject
    {
        public static function getObjectChild()
        {
            return self::getObject();
        }
    }
    
    $obj = ChildObject::getObjectChild();
    
    
    echo '<pre>' . print_r($obj) . '</pre>';
    
     

     

    the print_r will show ParentObject, but if u change the ParentObject::getObject() to :

     

     

    class ParentObject
    {
        protected static function getObject()
        {
            return new static();
        }
    }
     

     print_r will show ChildObject();

     

    CMIIW


     

  5. SOLVED

     

    for solution see the last part of my first post

     

    _______________________________________________________________________

    hi , i read chapter 3 and try to pass session_set_save_handler with an object,

     

    here's the code for my session handler class:

     

    <?php
    
    class MySessionHandler implements SessionHandlerInterface
    {
        protected $conn = NULL;
        
        public function open($savePath, $sessionName)
        {
            if(is_null($this->conn))
            {
                $dsn = 'mysql:host=localhost;dbname=php_advanced';
                $username = 'root';
                $password = 'password';
                try
                {
                     $this->conn = new PDO($dsn, $username, $password);
                     $this->conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
                }
                catch(PDOException $e)
                {
                     $this->conn = NULL;
                     die('error in open function ' . $e->getMessage());
                }
            }
            return TRUE;
        }
        
        public function close()
        {
              
            echo '<p>close</p>';
            $this->conn = NULL;
            
            return TRUE;
        }
        
        public function read($id)
        {
              
            echo '<p>read</p>';
            $query = 'SELECT data FROM session_table WHERE session_id = :id';
            try
            {
                $pdo = $this->conn->prepare($query);
                $pdo->bindValue(':id', $id);
                $pdo->execute();
                
                //    Kalo query berhasil nemuin id..
                if($pdo->rowCount() == 1)
                {
                    list($sessionData) = $pdo->fetch();
                    
                    return $sessionData;
                }
               
                return FALSE;
            }
            catch(PDOException $e)
            {
                $this->conn = NULL;
                die('error in read function => ' . $e->getMessage());
            }
            
        }
        
        public function write($id, $data)
        {
              
            echo '<p>write</p>';
            $query = 'REPLACE INTO session_table(session_id, data) VALUES(:id, :data)';
            
            try
            {
                $pdo = $this->conn->prepare($query);
                $pdo->bindValue(':id', $id);
                $pdo->bindValue(':data', $data);
                $pdo->execute();
                
                // return the value whether its success or not
                return (bool)$pdo->rowCount();
            }
            catch(PDOException $e)
            {
                $this->conn = NULL;
                die('error in write function => ' . $e->getMessage());
            }
        }
        
        public function destroy($id)
        {
              
            echo '<p>destroy</p>';
            $query = 'DELETE FROM session_table WHERE session_id = :id LIMIT 1';
            
            try
            {
                $pdo = $this->conn->prepare($query);
                $pdo->bindValue(':id', $id);
                $pdo->execute();
                $_SESSION = array();
                return (bool)$pdo->rowCount();
            }
            catch(PDOException $e)
            {
                $this->conn = NULL;
                die('error in destroy function => ' . $e->getMessage());
            }
        }
    
        public function gc($maxLifeTime)
        {
              
            echo '<p>garbage collection</p>';
            $query = 'DELETE FROM session_table WHERE DATE_ADD(last_accessed INTERVAL :time SECOND) < NOW()';
            
            try
            {
                $pdo = $this->conn->prepare($query);
                $pdo->bindValue(':time', $maxLifeTime);
                $pdo->execute();
                
                return TRUE;
            }
            catch(PDOException $e)
            {
                $this->conn = NULL;
                die('error in gc function => ' . $e->getMessage());
            }
        }
    }
    
    $SessionHandler = new MySessionHandler();
    session_set_save_handler($SessionHandler);
    session_name('my_session');
    
    session_start();
    
     
     

     

     

    i remove the session_write_close on purpose. This probably sounds stupid, but i want to get the session error to learn more..

     

    here's session script(using Larry's code):


     

    
    <?php
    
    require('session_class.php');
    ?><!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>DB Session Test</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
    <?php
    // Store some dummy data in the session, if no data is present:
    if (empty($_SESSION)) {
    
        $_SESSION['blah'] = 'umlaut';
        $_SESSION['this'] = 3615684.45;
        $_SESSION['that'] = 'blue';
        
        // Print a message indicating what's going on:
        echo '<p>Session data stored.</p>';
        
    } else { // Print the already-stored data:
        echo '<p>Session Data Exists:<pre>' . print_r($_SESSION, 1) . '</pre></p>';
    }
    
    // Log the user out, if applicable:
    if (isset($_GET['logout'])) {
    
        session_destroy();
        echo '<p>Session destroyed.</p>';
    } else { // Otherwise, print the "Log Out" link:
        echo '<a href="session_link.php?logout=true">Log Out</a>';
    }
    
    // Reprint the session data:
    echo '<p>Session Data:<pre>' . print_r($_SESSION, 1) . '</pre></p>';
    
    // Complete the page:
    echo '</body>
    </html>';
    
    // Write and close the session:
    // session_write_close <<<<<--- I REMOVE THIS ON PURPOSE TO GET ERROR
    ?>
     

     

     

     

    but i dont get any error, then i try to use Larry's mysqli script to connect db and it produces error..

     

    can anyone explain why if im using PDO it doesn't generate error? i'm even dont use

     

    register_shutdown_function('session_write_close');
     

    in my session class destructor (on purpose)

     

    NOTE : I'm doing this on purpose because i want to learn more.

     

    the error im expecting is like when im using mysqli connection(connection closed  by php at the end of script then session try to write and close but no connection available) :

     


     

    Warning: mysqli_real_escape_string() expects parameter 1 to be mysqli, null given in /var/www/ullman_advance/ch3/ullman_db.php on line 66
    
    
    
    Warning: mysqli_real_escape_string() expects parameter 1 to be mysqli, null given in /var/www/ullman_advance/ch3/ullman_db.php on line 66
    
    
    
    Warning: mysqli_query() expects parameter 1 to be mysqli, null given in /var/www/ullman_advance/ch3/ullman_db.php on line 67
    
    
    
    Warning: mysqli_close() expects parameter 1 to be mysqli, null given in /var/www/ullman_advance/ch3/ullman_db.php on line 33
     
    
     

     

     

    UPDATE

     

    i just tried to pass session_set_save_handler with function callback(using pdo as connection) and it produces error i expected, but still if using MySessionHandler class it doesn't produce any error. The codes in the MySessionHandler class is similar with my new session handler functions.

     

    here's the script

     

     

    <?php
    
    $conn = NULL;
    
    function open_session()
    {
        echo '<p>open session</p>';
        global $conn;
        $_dsn = 'mysql:host=localhost;dbname=php_advanced';
        $_username = 'root';
        $_password = 'monyetsahur';
        $conn = new PDO($_dsn, $_username, $_password);
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        
        return TRUE;
    }
    
    function close_session()
    {
        echo '<p>close session</p>';
        global $conn;
        
        $conn = NULL;
        return TRUE;
    }
    
    function read_session($sid)
    {
        echo '<p>read session</p>';
        global $conn;
        
        $query = 'SELECT data FROM session_table WHERE session_id = :sid';
        $pdo = $conn->prepare($query);
        $pdo->bindValue(':sid', $sid, PDO::PARAM_STR);
        $pdo->execute();
        
        if($pdo->rowCount() == 1)
        {
            list($session_data) = $pdo->fetch();
            echo '<pre>';
            print_r($session_data);
            echo '</pre>';
            
            return $session_data;
        }
        else
        {
            return '';
        }
    }
    
     
    function write_session($sid, $data)
    {
        echo '<p>write session</p>';
        global $conn;
        
        $query = 'REPLACE INTO session_table(session_id, data) VALUES(:sid, :data)';
        $pdo = $conn->prepare($query);
        $pdo->bindValue(':sid', $sid, PDO::PARAM_STR);
        $pdo->bindValue(':data', $data, PDO::PARAM_STR);
        $pdo->execute();
        
        return (bool)$pdo->rowCount();
    }
    
    function destroy_session($sid)
    {
        echo '<p>destroy session </p>';
        global $conn;
        
        $query = 'DELETE FROM session_table WHERE session_id = :sid';
        $pdo = $conn->prepare($query);
        $pdo->bindValue(':sid', $sid, PDO::PARAM_STR);
        $pdo->execute();
        
        // clean the session array;
        $_SESSION = array();
        
        return TRUE
    }
    
    
    function clean_session($expire)
    {
        echo '<p>clean session</p>';
        global $conn;
        
        $query = 'DELETE FROM session_table WHERE DATE_ADD(last_accessed, INTERVAL :expire SECOND) < NOW()';
        
        $pdo = $conn->prepare($query);
        $pdo->bindValue(':expire', $expire, PDO::PARAM_INT);
        $pdo->execute();
        
        return $pdo->rowCount();
    }
     
    session_set_save_handler('open_session', 'close_session', 'read_session', 'write_session', 'destroy_session', 'clean_session');
    session_name('my_session');
    session_start();
    
    
    SOLVED:
    
    

    SOLVED


    sorry guys my mistake actually
    its a pretty easy answer why MySessionHandler class doesnt produce
    error wihtout session_write_close() in the end of script,

    session_set_save_handler() by default will register session_write_close() to register_shutdown_function()

    so if u want to make your own shutdown function for session then use :

     


     

    session_set_save_handler($SessionClass, FALSE)
     

     

     

     

    if u do this then u must provide session_write_close() in your class destructor

    source : http://php.net/manual/en/function.session-set-save-handler.php

    thanks for the tips and your attention 

  6. I just read about hash_hmac() function in this book, it says something about that hash_hmac() function return a string that would potentially breaks the query


    so i tried to use it for storing password in DB , by using PDO
     

     

    <?php
        $dsn = 'mysql:host=localhost;dbname=test';
        $username = 'root';    
        $pass = 'password';
        $conn = new PDO($dsn, $username, $pass);
    
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);         
        $conn->setAttribute(PDO::ATTR_PERSISTENT, TRUE);
        $password = '123MonyeTSahuR456';            
        
    $p addslashes(hash_hmac('sha256',$password,'13#slP3mK;"dA$@m',TRUE));                
    $query = "INSERT INTO table_one VALUES(NULL, :password)";        
    try    
    {
            $pdo = $conn->prepare($query);        
            $pdo->bindValue(':password', $p);
            if($pdo->execute())        
            {            
                echo $pdo->rowCount();        
            }        
            else        
            {            
                echo 'fail';
            }
    }    
    catch(PDOException $e)    
    {        
             echo $e->getMessage();    
    }
     
    
     

     



     

    **the DB details:**

    id INT NOT NULL AUTO INCREMENT    password VARBINARY(32) NOT NULL



    after that i manually check my DB and found a row with BLOB(i never work/use with VARBINARY or BLOB data type before, so this is my first time)

    so there's 1 row exist and i try to select the row :
     

    $query = "SELECT * FROM table_one WHERE password = :password";



    the value returned by pdo->rowCount() is 0 , it doesn't find the password im looking for.

    but when i use it without addslashes(), it works, why is this happen?

    **another details :**

    PHP version : 5.4

    OS : Ubuntu 12.04 64 bit
    thanks

    EDIT:

    Sry my bad.. i just remember that PDO will escaped the query if using prepared statements..
    btw i just tried using PDO::bindValue with PDO::PARAM_LOB and it works even with addslashes function, can anyone explain?

  7. hi guys :D!

     

    i have question about output buffering(chapter 18 page 561)

     

    i have searched google about it and it came with alot of debates, some say its good practice, some say its bad practice to use it, but they dont provide any code for testing why its good and why its bad..

     

    so the question is :

    is it a good practice to always use it ? as Larry's statement in the book that says

    "There can be a performance improvement with output buffering, but the main benefit is that it eradicates those pesky headers already sent error messages."

     

    if its bad practice, please give good reasons + codes(if neccessary) to prove why its bad

  8. i think the problem lies here :

    $errors = array();
    
    if(empty($email))
    {
    $errors[] = "You forgot to enter the email";
    }
    else
    {
    $email = mysqli_real_escape_string($conn, trim($email));
    }
    
    if(empty($pass))
    {
    $errors[] = "You forgot to enter the password";
    }
    else
    {
    $pass = mysqli_real_escape_string($conn, trim($pass));
    }
    

     

    because i use $errors = array();

     

    what im thinking is like this, a bit mess up but solve the problem even tough its not the best way

    $errors = '';
    if(empty($email))
    {
    $errors = 'You forgot to enter the email';
    }
    else
    {
    $email = mysqli_real_escape_string($conn, trim($email));
    }
    if(empty($pass))
    {
    if(!empty($errors)) //if there is a string in $errors
    {
     $tmp = $errors;
     $errors = array();
     $errors[] = $tmp;
     $errors[] = 'You forgot to enter password';
    }
    else
    {
     $errors = 'You forgot to enter password';
    }
    }
    else
    {
    $pass = mysqli_real_escape_string($conn, trim($pass));
    }
    

     

    then i use

    if(is_array($errors))
    {
       foreach($errors as $error)
       echo $error;
    }
    else
    {
       echo $errors
    }
    

     

    i dont know any better way to do this, if anyone can give me some tips please do, i will really appreciate it :D

  9. Hello guys, this is my first question as well as my first post in this community

     

    Add code to the handling of the $errors variable on the login page that uses a foreach loop if $errors is an array, or just prints the value of $errors otherwise.

     

    what im thinking is using is_array() function, to test $errors :

     

    if( is_array($errors) )
    

     

    then i tried to use var_dump() to test $errors (even if there is only 1 error) unfortunately its still an array.

     

    i cant figure it out, i really appreciate any help, but please dont post any code, just tell me what to do :)

×
×
  • Create New...