Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从静态方法中的另一个类调用非静态方法_Php_Oop - Fatal编程技术网

Php 从静态方法中的另一个类调用非静态方法

Php 从静态方法中的另一个类调用非静态方法,php,oop,Php,Oop,我想在静态方法中从我的数据库类调用一个非静态方法 未捕获错误:在E:\xampp\htdocs\danacrm\libs\Setting.php:32中调用null上的成员函数select() 我的解决方案是什么 这是我的数据库类: [路径:../libs/Database.php] class Database extends PDO { function __construct($DB_TYPE, $DB_HOST, $DB_NAME, $DB_USER, $

我想在静态方法中从我的数据库类调用一个非静态方法

未捕获错误:在E:\xampp\htdocs\danacrm\libs\Setting.php:32中调用null上的成员函数select()

我的解决方案是什么

这是我的数据库类: [路径:../libs/Database.php]

    class Database extends PDO
    {
        function __construct($DB_TYPE, $DB_HOST, $DB_NAME, $DB_USER, $DB_PASS)
        {
            parent::__construct($DB_TYPE . ':host=' . $DB_HOST . ';dbname=' . $DB_NAME, $DB_USER, $DB_PASS,array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
        }

        public function select($SQL,$array=array(),$fetch_style=  PDO::FETCH_ASSOC) {

            $query = $this->prepare($SQL);
            foreach ($array as $key => $value) {
                $query->bindvalue(":$key", $value);
            }
            $query->execute();

            return $query->fetchAll($fetch_style);
        }
        public function insert($table, $data) {
            ksort($data);

            $fieldkey = implode('`, `', array_keys($data));
            $fieldvalue = ':' . implode(', :', array_keys($data));

            $query = $this->prepare("INSERT INTO  $table
                  ( `$fieldkey` )
           VALUES ( $fieldvalue )");

            foreach ($data as $key => $value) {
                $query->bindvalue(":$key", $value);
            }

            return $query->execute();

        }

        public function update($table, $data, $where) {
            ksort($data);
            $fieldDetails = "";
            foreach ($data as $key => $value) {
                $fieldDetails .= " `$key`= :$key ,";
            }
            $fieldDetails = rtrim($fieldDetails, ' ,');

            $query = $this->prepare("UPDATE $table  SET $fieldDetails  WHERE $where");


            foreach ($data as $key => $value) {

                $query->bindvalue(":$key", $value);
            }
            if($query->execute())
                return true;

            return false;
        }
        public function delete($table,$where) {
            $query = $this->prepare("DELETE FROM  $table  WHERE $where");
            return   $query->execute();
        }
    }
我的设置类:[path:../libs/Setting.php]

class Setting
{

    protected static $db;

    function __construct()
    {
        self::$db = new Database(DB_TYPE,DB_HOST,DB_NAME,DB_USER,DB_PASS);
    }

    // I wanna use this method in whole of my project
    public static function options($option_name = false)
    {
        if ($option_name) {
            $options = self::$db->select("SELECT * FROM `options` WHERE `option_name` = '$option_name'");
            if(!empty($options[0]))
            {
                return $options[0];
            }
            else
            {
                return false;
            }
        } else {
            $options = self::$db->select("SELECT * FROM `options`");
        }
        return $options;
    }

}

根据Sahil Gulati和Yupik在评论中提到的内容,您需要首先实例化
数据库
类,然后才能实际调用它的方法

因为静态类不需要实例化(可以),所以应该注意,在使用之前需要实例化的静态类中的所有属性都是首先调用的。此选项的一个选项是使用一些启动器功能,将必要的对象设置为运动状态。:)

用法:

Setting::initiate();
Setting::options('some option name');

你在那里做了很多错事

不要结束PDO类 PDO已经是DB acces抽象。您不需要抽象抽象。您的代码中也存在错误,这使得您的代码容易受到SQL注入的攻击。请检查链接的手册文章,并特别注意
bindParam()
bindValue()
方法的使用。您还可以观看(示例中使用了mysqli,但核心机制是相同的),这应该可以解释注入漏洞的实际来源

使用依赖注入 您当前的代码依赖于全局状态。相反,您应该将PDO实例作为依赖项注入
设置
服务中

实际上,它看起来是这样的:

class Setting {
    privare $connection;

    public function __construct(PDO $connection) {
        $this->connection = $connection;
    }

    public function options($option_name) {
        // codes here
    }
};
这个想法基本上是:

$db = new PDO;
$foo = new Foo($db);
$bar = new Bar($db);
这样,
Foo
Bar
实例都具有相同的数据库连接


强烈建议观看

移动此行
self::$db=新数据库(db\u类型、db\u主机、db\u名称、db\u用户、db\u密码)内部
设置::选项
我的问题解决了谢谢♥非常感谢。但是有一个小问题!这是设置类,我想用静态方法在整个项目中调用它!我该怎么做?对于这样的东西,最好的选择是在顶层使用
Setttings
类,这就是传播值的方式。主要问题是代码本质上是用全局状态编写的,这就是为什么您认为需要一些神奇的全局“设置”类。
$db = new PDO;
$foo = new Foo($db);
$bar = new Bar($db);