Я хочу создать свой собственный класс, который я могу использовать для взаимодействия с базой данных,
и я думаю, что было бы легко и удобно читать, если бы я использовал цепочку методов.
Но у меня проблема с вызовом первого метода статически.
Вот код:
<?php
class Crud
{
protected static $action;
protected static $instance = null;
protected static $columns = [];
protected $data;
protected $db;
protected $query;
protected $table;
public function __construct()
{
$this->db = new mysqli('localhost', 'root', '', 'bahan_belajar');
if (!$this->db) {
echo "error";
}
return $this;
}
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self;
}
return self::$instance;
}
public function select()
{
if (empty(func_get_args())) {
// $this->columns = "*";
self::$columns = "*";
} else {
if (is_array(func_get_args())) {
// self::columns = join(', ', func_get_args());
self::$columns = join(', ', func_get_args());
} else {
// self::columns = func_get_args();
self::$columns = func_get_args();
}
}
self::$action = "SELECT";
return $this;
}
public function from($tableName)
{
$this->table = ' FROM ' . $tableName;
return $this;
}
public function get($getName = 'object')
{
$this->query = self::$action . ' ' . self::$columns . ' ' . $this->table;
switch ($getName) {
case 'object':
$this->data = $this->db->query($this->query)->fetch_object();
break;
case 'array':
$this->data = $this->db->query($this->query)->fetch_array();
break;
case 'count':
$this->data = $this->db->query($this->query)->num_rows;
break;
}
return $this->data;
}
}
$chat = Crud::getInstance()->select('nama', 'teks')->from('chat')->get();echo '<pre>';
print_r($chat);
echo '</pre>';
На самом деле, этот код работает нормально, если я использую getInstance()
Метод сначала, как показано выше. Но как я могу заставить его работать, когда я вызываю метод select () напрямую как статический метод, такой как:
$chat = Crud::select('nama', 'teks')->from('chat')->get();
Если я выполню код выше, я получу ошибку, такую как:
Фатальная ошибка: Ошибка Uncaught: использование $ this, когда оно не в контексте объекта в C: \ xampp \ htdocs \ bahan_belajar \ chat \ classes.php: 47 Трассировка стека: # 0 C: \ xampp \ htdocs \ bahan_belajar \ chat \ classes.php (74 ): Crud :: select (‘nama’, ‘teks’) # 1 {main} добавлено C: \ XAMPP \ HTDOCS \ bahan_belajar \ чат \ classes.php онлайн 47
Я знаю, что метод select () должен быть статическим методом, прежде чем он может быть вызван с ::
(Я думаю), но как я могу сделать это статичным?
Вы можете использовать только ::
со статическими методами и ->
с методами экземпляра. Это оставляет вам 2 варианта:
Вам нужно получить экземпляр с вашим статическим методом, а затем использовать ->
цепочкой, вот так:
Crud::getInstance()->select('nama', 'teks')->from('chat')->get();
Ваш другой вариант, чтобы стать модным с магические методы. Если вы делаете свои методы protected
или же private
, вы можете перехватывать вызовы этих методов извне класса с помощью __call()
а также __callStatic()
магические методы. Когда ты в __callStatic()
, вы можете переключиться на использование экземпляра, вызвав self::getInstance()
,
Такой подход позволит вам сделать что-то вроде
Crud::select('nama', 'teks')->from('chat')->get();
Вот несколько очень упрощенных примеров кода, чтобы продемонстрировать идею (демо на 3в4л):
class Test
{
public static $instance;
protected $myVar = 'foo';
// This intercepts instance calls ($testObj->whatever()) and handles them
public function __call($name, $args)
{
return call_user_func_array(array($this, $name), $args);
}
// This intercepts instance calls ($testObj->whatever()) and handles them
// The use of self::getInstance() lets us force static methods to act like instance methods
public static function __callStatic($name, $args)
{
return call_user_func_array(array(self::getInstance(), $name), $args);
}
public static function getInstance()
{
return self::$instance ? : new self;
}
protected function getMyVar()
{
echo $this->myVar;
}
protected function setMyVar($value)
{
$this->myVar = $value;
return $this;
}
}
echo Test::setMyVar(15)->getMyVar(); // successfully echoes 15
Важное замечание ко всему этому: то, что вы делаете, очень похоже на переизобретение Красноречивый ORM, который поставляется вместе с Laravel. Возьмите его от кого-то, кто раньше создавал свой собственный ORM: вам лучше использовать существующую систему, такую как Eloquent, которая уже была написана и тщательно протестирована (и ее можно использовать, не требуя от вас использования всей среды Laravel). Построение ORM — это много сложнее, чем кажется, и, как только вы начнете, кроличья нора просто становится глубже.
Других решений пока нет …