[英]Call non static method from another class in static method
我想以静态方法从数据库类中调用非静态方法。
未捕获的错误:在E:\\ xampp \\ htdocs \\ danacrm \\ libs \\ Setting.php:32中以null调用成员函数select()
我的解决方案是什么?
这是我的数据库类:[path:../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;
}
}
您在这里做错了很多事情。
PDO已经是数据库访问的抽象。 您不需要抽象该抽象。 您还在代码中错误地执行了准备好的语句 ,这使您的代码容易受到SQL注入的攻击。 请检查链接的手册文章,并特别注意使用bindParam()
和bindValue()
方法。 您也可以观看此视频 (示例中使用mysqli,但核心机制相同),该视频应说明注入漏洞的真正来源。
您当前的代码依赖于全局状态。 相反,您应该将PDO实例作为依赖项注入到Settings
服务中。
实际上,它看起来像这样:
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
实例都具有相同的数据库连接。
强烈建议观看此讲座 。
根据注释中提到的Sahil Gulati和Yupik,您需要首先实例化Database
类,然后才能实际调用它的方法。
由于静态类不需要实例化(可以),因此应注意,在使用之前需要实例化静态类中所有需要实例化的属性。 一种选择是拥有一些启动器功能,该功能可以将必要的对象设置为运动状态。 :)
class Database {
public function select($sql) {
//code here
}
};
class Setting {
protected static $db;
public static function initiate() {
self::$db = new Database();
}
public static function options($option_name) {
// codes here
}
};
用法:
Setting::initiate();
Setting::options('some option name');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.