Search code examples
phpmysqlpdophp-5.4

Modifying / Adding extra stuff to PDO bindParam()?


does anyone know by any chance if there is a clean way (or any way at all) to change PDO's bindParam?

We're implementing extra security measures for our websites (filters for inputs) and so far it seems that the best way to add it to every single website we have efficiently (every website we have is different but the thing they have in common is they all use PDO) would be to somehow make PDO bindParam call our function on it's parameters, so that every single input in the bindParam would be filtered appropriately.

Thanks!


Solution

  • Solved this by extending PDO classes:

    class CustomDBConnection {
    
        private static $conn;
    
        // either create a new connection or return an existing one
        public static function getInstance() {
            if (self::$conn == null) {
                global $db_hostname, $db_database, $db_username, $db_password; // probably better to store these within this class but this was quicker
                self::$conn = new CustomPDO("mysql:host=$db_hostname;dbname=$db_database;charset=utf8", $db_username, $db_password, array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
            }
    
            return self::$conn;
        }
    }
    
    class CustomPDO extends PDO {
    
        public function __construct($dsn, $username = null, $password = null, $driver_options = array()) {
    
            parent::__construct($dsn, $username, $password, $driver_options);
    
            // Attach customised PDOStatement class
            $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('CustomPDOStatement', array($this)));
        }
    }
    
    class CustomPDOStatement extends PDOStatement {
    
        private $conn;
    
        protected function __construct($conn) {
            $this->conn = $conn; // this is most likely useless at this moment
        }
    
        public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null) {
            $variable = InputProtection::detachEvilHTML($variable);
    
            parent::bindParam($parameter, $variable, $data_type, $length, $driver_options);
        }
    
        public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR) {
            $value = InputProtection::detachEvilHTML($value);
    
            parent::bindValue($parameter, $value, $data_type);
        }
    }
    

    So I basically do $db = CustomDBConnection::getInstance(); now instead of $db = new PDO(.......);