致命错误:在.... / abstractmodel.php 98中调用null上的成员函数execute()

时间:2017-04-16 03:55:42

标签: php mysql oop

我尝试学习如何制作MVC模型,但我有以下错误: 注意:抱歉,没有在....... / pdodatabasehandler.php中找到方法准备27 致命错误:在.... / abstractmodel.php 98

中调用null上的成员函数execute()

databasehandler.php

   <?php
namespace BATRAHOSTMVC\Lib\Database;
/**
 * Description of DatabaseHandler
 *
 * @author Mohamed Hassan Elmetwaly
 * 25-03-2017
 * mhe.developer@gmail.com
 */
abstract class DatabaseHandler {
    const DATABASE_DRIVER_POD = 1;
    const DATABASE_DRIVER_MYSQLI = 2;

    private function __construct() {

    }
    abstract protected static function init();
    abstract protected static function getInstance();
    public static function factory()
    {
      //  $driver = DATABASE_CONN_DRIVER;
     //  if($driver == self::DATABASE_DRIVER_POD)
      // {
          return PDODatabaseHandler::getInstance();

      // } else if ($driver == self::DATABASE_DRIVER_MYSQLI)
     //  {
      //     return MySQLiDatabaseHandler::getInstance();
      // }       
    }
}

pdodatabasehandler.php

    <?php
namespace BATRAHOSTMVC\Lib\Database;
/**
 * Description of pdodatabasehandler

 * @author Mohamed Hassan Elmetwaly
 * 25-03-2017
 * mhe.developer@gmail.com
 */


class PDODatabaseHandler extends DatabaseHandler
{
    private static $_instance;
    private static $_handler;

    private function __construct() {
        self::init();
    }
    //public function __call($name, $arguments) {}

   public function __call($name, $arguments) {
       if(method_exists($this, $name))
       {
           $this->$name($arguments);
       } else {
           trigger_error('Sorry no method '. $name. ' has been found');
       }

   }    

    protected static function init(){
        try{

            self::$_handler = new \PDO(
                    'mysql:host='.DATABASE_HOST_NAME.';dbname='.DATABASE_DB_NAME,DATABASE_USER_NAME,
                    DATABASE_PASSW0RD);
            //var_dump(self::$_handler);
            //self::$_handler = new pdo("mysql:host=localhost; dbname=test", 'root', 'rootbootroot');
            //return 'Connected';

        } catch (\PDOException $e)
        {
            echo $e->getMessage( ) ." | ". $e->getCode( ) ;

        }

    }
    public static function getInstance() {
        if(self::$_instance === null){
            self::$_instance = new self();
        }
        return self::$_instance;
    }



}

abstractmodel.php

   <?php
namespace BATRAHOSTMVC\Models;
use BATRAHOSTMVC\Lib\Database\DatabaseHandler;
//echo DATABASE_DB_NAME;
/**
 * Description of abstractmodel
 * @author Mohamed Hassn Elmetwaly (25-03-2017)
 * mhe.developer@gmail.com
 */
class AbstractModel 
{
    const DATA_TYPE_BOOL = \PDO::PARAM_BOOL;
    const DATA_TYPE_STR = \PDO::PARAM_STR;
    const DATA_TYPE_INT = \PDO::PARAM_INT;
    const DATA_TYPE_DECIMAL = 4;
    const DATA_TYPE_DATE = 5;
    /*
    public static function viewTableSchema()
    {
        return static::$tableSchema;
    }
     * 
     */
    // we make path by reference 
    private function prepareValues(\PDOStatement &$stmt)
    {
          foreach (static::$tableSchema as $columnName => $type)
        {
            if($type == 4)
            {
                $sanitizedValue = filter_var($this->$columnName, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
                $stmt->bindValue(":{$columnName}", $sanitizedValue);
            }
            else
            {
                $stmt->bindValue(":{$columnName}", $this->$columnName,  $type);
            }

        }      
    }

        private static function buildNameParametersSQL()
    {
        $nameParams = '';
        //$columnName (Column Name) => $type (Column datatype)
        foreach (static::$tableSchema as $columnName => $type)
        {
            $nameParams .= $columnName. ' = :'.$columnName. ', ';
        }
        return trim($nameParams, ', ');
    }

    private static function create()
    {
        //global $connection;

        $sql = 'INSERT INTO '. static::$tableName . ' SET '. self::buildNameParametersSQL();
        $stmt = DatabaseHandler::factory()->prepare($sql);
        $this->prepareValues($stmt);
        return $stmt->execute(); // true of false
    }

    private static function update()
    {
       // global $connection; 
        $sql = 'UPDATE '. static::$tableName . ' SET '. self::buildNameParametersSQL(). ' WHERE '. static::$primaryKey .' = '.$this->{static::$primaryKey};
      //  $stmt = $connection->prepare($sql);
        //$stmt = DatabaseHandler::factory()->prepare($sql);
        $stmt = DatabaseHandler::factory()->prepare($sql);
        $this->prepareValues($stmt);
        return $stmt->execute(); // true of false
    }

    public function save()
    {
        return $this->{static::$primaryKey} === null ? $this->create() : $this->update();
    }

    public static function delete()
    {
      //  global $connection; 
        $sql = 'DELETE FROM '. static::$tableName . ' WHERE '. static::$primaryKey .' = '.$this->{static::$primaryKey};
       // $stmt = $connection->prepare($sql);
        $stmt = DatabaseHandler::factory()->prepare($sql);
        return $stmt->execute(); // true of false
    }

    public static function getAll()
    {
       // global $connection; 
        $sql = 'SELECT * FROM '. static::$tableName;
        //$stmt = $connection->prepare($sql);
        $stmt = DatabaseHandler::factory()->prepare($sql);
        //return $connection->execute() === true ? $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, 'Employee', array('name', 'age', 'address', 'tax', 'salary')) : false;
        //using fetchAll with this paramaters return values as OBJECT Of class which returned by get_called_calss() which called this method
        $stmt->execute();
        $result = $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, get_called_class(), array_keys(static::$tableSchema));
        return is_array($result) && !empty($result) === true ? $result : false;
    }

    public static function getByPk($pk)
    {
        //global $connection; 
        $sql = 'SELECT * FROM '. static::$tableName. ' WHERE '. static::$primaryKey .' = '.$pk;
        //$stmt = $connection->prepare($sql);
        //$stmt = DatabaseHandler::factory()->prepare($sql);
        $stmt = DatabaseHandler::factory()->prepare($sql);
        //return $connection->execute() === true ? $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, 'Employee', array('name', 'age', 'address', 'tax', 'salary')) : false;
        //using fetchAll with this paramaters return values as OBJECT Of class which returned by get_called_calss() which called this method
        if($connection->execute() === true)
        {
            $obj = $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, get_called_class(), array_keys(static::$tableSchema));
            return array_shift($obj);
        }
        return false;
    }

    public static function get($sql, $options = array())
    {
        /*
         * example:
         * $emps = Employee::get(
         * 'SELECT name, age FROM employees WHERE age = :age',
         * array(
         * 'age' => array(Employee::DATA_TYPE_INT, 34)
         * )
         * )
         * var_dump($emps)
         */

        //global $connection;
        //$stmt = $connection->prepare($sql);
        $stmt = DatabaseHandler::factory()->prepare($sql);
        if(!empty($options))
        {
         foreach ($options as $columnName => $type)
        {
            //$type[0] = datatype, $type[1] = columname
            if($type[0] == 4)
            {
                $sanitizedValue = filter_var($type[1], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
                $stmt->bindValue(":{$columnName}", $sanitizedValue);
            }
            else
            {
                $stmt->bindValue(":{$columnName}", $type[1], $type[0]);
            }

        }            
        }
        $stmt->execute();
                $result = $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, get_called_class(), array_keys(static::$tableSchema));
                return is_array($result) && !empty($result) === true ? $result : false;
        /*        
        if(method_exists(get_called_class(), '__construct')){
        $result = $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, get_called_class(), array_keys(static::$tableSchema));
        //return is_array($result) && !empty($result) === true ? $result : false;
        } else {
        $result =$stmt->fetchAll(\PDO::FETCH_CLASS, get_called_class());    
        }
        if((is_array($result) && !empty($result))){
            $generator = function() use ($result){};
            return $generator;
        }
        return false;

         */

    }
}

employeecontroller.php

    <?php

/**
 * Description of abstractcontroller
 *
 * @author Mohamed Hassn Elmetwaly (25-03-2017)
 * mhe.developer@gmail.com
 */

namespace BATRAHOSTMVC\Controllers;
use BATRAHOSTMVC\Models\EmployeeModel;

class EmployeeController extends AbstractController
{

    public function defaultAction()
    {
        //EmployeeModel::getAll();
        var_dump(EmployeeModel::getAll());
        $this->_view();
    }
}

employeemodel.php

   <?php
namespace BATRAHOSTMVC\Models;
//use BATRAHOSTMVC\Models\AbstractModel;
//use BATRAHOSTMVC\Models\AbstractModel;
/**
 * Description of employee
 * @author Mohamed Hassn Elmetwaly (25-03-2017)
 * mhe.developer@gmail.com
 */

class EmployeeModel extends AbstractModel
{
    public $id;
    public $name;
    public $age;
    public $address;
    public $tax;
    public $salary;

    public static $db;
    protected static $tableName = 'employees';
    protected static $tableSchema = array(
      'name'        => self::DATA_TYPE_STR,
      'age'        => self::DATA_TYPE_INT,
      'address'        => self::DATA_TYPE_STR,
      'tax'        => self::DATA_TYPE_DECIMAL,
      'salary'        => self::DATA_TYPE_DECIMAL
    );
    protected static $primaryKey = 'id';
    public function __construct($name, $age, $address, $tax, $salary) {


        $this->name = $name;
        $this->age = $age;
        $this->address = $address;
        $this->tax = $tax;
        $this->salary = $salary;


    }
    public function __get($prop){
        $this->$prop;
    }
    public function getTableName(){
        return self::$tableName;
    }

}

autoload.php

  <?php
namespace BATRAHOSTMVC\LIB;

/*
 * Applcation Constants
 */
/*
define('DS', DIRECTORY_SEPARATOR);
define('APP_PATH', dirname(realpath(__FILE__)).DS.'..');

define('PS', PATH_SEPARATOR);
define('CONTROLLER_PATH', APP_PATH.DS.'controllers');
define('MODEL_PATH', APP_PATH.DS.'models');
//echo CONTROLLER_PATH;
$path = get_include_path().PS.CONTROLLER_PATH.PS.MODEL_PATH;
set_include_path($path);

 */
class Autoload
{
    public static function autoload($classname)
    {
      /* in Explanation */
      $classname = str_replace('BATRAHOSTMVC', '',$classname);
      $classname = str_replace('\\', '/', $classname);
      $classname = $classname.'.php';
      $classname = strtolower($classname);
        if(file_exists(APP_PATH.$classname))
        {
             require_once APP_PATH.$classname;
        }
     /*   
     $class = str_replace('\\', '/', $classname);
     $classFile = APP_PATH.DIRECTORY_SEPARATOR.strtolower($class).'.php';
     if(file_exists($classFile))
        {
             require $classFile;
        }
        else
        {
            return;
        }

      */
    }
}
spl_autoload_register(__NAMESPACE__.'\Autoload::autoload');

frontcontroller.php

    <?php

namespace BATRAHOSTMVC\LIB;

class FrontController
{
    const NOT_FOUND_ACTION = 'notFoundAction';
    const NOT_FOUND_CONTROLLER = 'BATRAHOSTMVC\Controllers\NotFoundController';

    private $_controller = 'index';
    private $_action = 'default';
    private $_params = array();

    public function __construct() {
        $this->_parseUrl();
    }

        private function _parseUrl()
    {
        $url = explode('/', trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH),'/'), 3);
        var_dump($url);
        if(isset($url[0]) && $url[0] !='')
        {
            $this->_controller = $url[0];
        }
        if(isset($url[1]) && $url[1] !='')
        {
            $this->_action = $url[1];
        }
        if(isset($url[2]) && $url[2] !='')
        {
            $this->_params = explode('/', $url[2]);
        }            
       // @list($this->_controller, $this->_action, $this->_params) = explode('/', trim($url, '/'),3);
      //  $this->_params = explode('/', $this->_params);
        var_dump($this);
    }

    public function dispatch()
    {
       $controllerClassName = 'BATRAHOSTMVC\Controllers\\'.ucfirst($this->_controller).'Controller';
       $actionName = $this->_action.'Action';
       if(!class_exists($controllerClassName))
       {
           $controllerClassName = self::NOT_FOUND_CONTROLLER;
       }
       $controller = new $controllerClassName();
       if(!method_exists($controller, $actionName))
       {
          $this->_action = $actionName = self::NOT_FOUND_ACTION;
       }
       $controller->setController($this->_controller);
       $controller->setAction($this->_action);
       $controller->setParams($this->_params);
       $controller->$actionName();
    }
}

我在以下链接中附加了我的文件 http://www.mediafire.com/file/mdbxj5o3f6hd3gz/mvcyahia%285-4-2017%29.rar

提前致谢

2 个答案:

答案 0 :(得分:0)

public static function getInstance() {
if(self::$_instance === null){
    self::$_instance = new self();
}

 // here was the confusing the old value was  return self::$_instance
return self::$_handler; 

}

答案 1 :(得分:-1)

您的数据库/查询对象为空。因此,找到如何调用数据库对象,以便调用其方法。

您的代码显示没有为您的db类定义prepare()方法。

您正在将PDODatabaseHandler :: _ handler属性设置为PDO,但是当您返回self()时。得到它?