Я много искал и какое-то время отвечал на мой вопрос о Переполнение стека но я не нашел ответа, ни здесь, ни где-либо еще.
В любом случае, я много раз пытался использовать драйверы CodeIgniter, но часто выходил из-за __вызов метод. Позвольте мне объяснить на примере.
Допустим, у меня есть водитель под названием Приложение (конечно, это расширяет CI_Driver_Library)
class App extends CI_Driver_Library
{
public $CI;
public $valid_drivers;
public function __constructor()
{
$this->CI &= get_instance();
$this->valid_drivers = ['users']; // An example.
}
}
Теперь у меня есть пользователи водитель вроде так.
class App_users extends CI_Driver
{
private $CI;
public function __construct()
{
$this->CI =& get_instance();
$this->CI->load->model('users_model');
}
public function __call($method, $params = [])
{
if (method_exists($this, $method)
{
return call_user_func_array(array($this, $method), $params);
}
elseif (method_exists($this->CI->users_model, $method))
{
return call_user_func_array(array($this->CI->users_model, $method), $params);
}
else
{
throw new BadMethodCallException("No such method: {$method}");
}
}
}
Я хочу загрузить Users_model в этом App_users __конструктор (возможно, но Родитель :: $ CI не доступно но мне удалось).
Проблема, с которой я сталкиваюсь, заключается в использовании __вызов метод для вызова метода этого драйвера ИЛИ ЖЕ метод модели. К сожалению, этот магический метод не работал и никогда не работал для меня. Как я могу сделать это, ребята, если это возможно? Если нет, есть ли обходной путь?
Заранее спасибо.
Прежде всего, вы должны знать, что первое условие
if (method_exists($this, $method)...
бессмысленно, потому что условие никогда не будет выполнено. __call
магически срабатывает, когда метод класса не может быть найден. Уже было установлено, что method_exists($this, $method)
неправда. Если бы это было ИСТИНА тогда __call()
не был бы запущен.
Удаление первого if
блокировать результаты в этом.
public function __call($method, $params = [])
{
if (method_exists($this->CI->users_model, $method))
{
return call_user_func_array(array($this->CI->users_model, $method), $params);
}
else
{
throw new BadMethodCallException("No such method: {$method}");
}
}
Это должно работать.
Если это не так, я должен спросить, какой код, который вы ожидаете, должен сработать __call
?
Редактировать в ответ на комментарий:
скажи мне пожалуйста .. Есть ли способ, которым ребенок может получить доступ к методам своего родного брата?
Моя первая реакция состоит в том, чтобы сказать, что, если у вас есть такая потребность, тогда «драйверы» могут не подходить для использования. Как реализовано в CI, драйверы представляют собой особый тип библиотеки, в которой есть родительский класс и любое количество потенциальных дочерних классов. Дочерние классы имеют доступ к родительскому классу, но не к своим братьям и сестрам.
Эта схема предназначена специально, поскольку обычно каждый драйвер предназначен для работы с устройством особого типа или конкретной услугой программного обеспечения. Например, в контексте баз данных каждый драйвер обрабатывает сервер баз данных определенного типа (то есть MySQL, SQLite) и / или расширение до типа сервера (то есть mysql, mysqli).
Библиотека CI CI_Cache
имеет драйверы для нескольких разных систем динамического кеширования. Эти системы имеют тенденцию быть взаимоисключающими. Я подозреваю, что пытаюсь бежать memcached
а также redis
в то же время может стать причиной сильных головных болей.
Вот эти примеры, почему мне интересно, если вы не выбрали неправильный шаблон программного обеспечения. По крайней мере, необходимость общения братьев и сестер имеет тенденцию указывать на неправильное мышление, когда дело доходит до разделение интересов.
Все, что сказал, я думаю, что решение состоит в том, чтобы поместить метод в родительский элемент, который обрабатывает рутинную работу. Этот метод будет вызываться от одного родного брата к родителю, который вызовет соответствующий метод другого родственного брата. Примечание: я не проверял эту идею. __call
может быть в состоянии справиться с этим, но мне кажется, что явные вызовы являются более чистым решением.
Если вы еще не нашли их, вот пара учебных пособий по драйверам CI, которые могут вам пригодиться. Кевин Филлипс а также codebyjeff
Других решений пока нет …