У меня есть синглтон следующего класса. Я пытаюсь добиться сбора ссылок на различные массивы результатов базы данных, которые вызываются по всему приложению, а затем, наконец, сделать один запрос к базе данных и получить некоторые замещающие значения (переводы) вместо того, чтобы делать это для каждого отдельного запроса.
Оставляя в стороне плюсы и минусы этого подхода, я не могу сделать фактическую замену «исходных» значений (результатов базы данных), которые передаются в translate()
метод по ссылке каждый раз, когда запрос отправляется на сервер БД.
class Translator {
public $translatableTables = ['content' => ['title', 'body']];
private $table = 'translations';
private $queue = array();
public function translate($table, &$results)
{
if(!isset($this->queue[$table])) {
$this->queue[$table] = array();
}
$this->queue[$table][] =& $results;
}
public function fetchTranslations()
{
foreach($this->queue as &$table) {
foreach($table as &$results) {
foreach($results as &$result) {
$result->content = 'DON\'T PANIC THIS IS A TEST';
}
}
}
var_dump($this->queue);
// dumps just the right data, so I know it's all been collected
}
}
Ближе к концу жизненного цикла запроса (но до генерации вывода) я вызываю fetchTranslations()
метод в том же экземпляре синглтона.
Я ожидаю, что исходные значения будут заменены на строку DON'T PANIC THIS IS A TEST
но это не работает
Есть мысли / идеи?
Редактировать: 3 вложенных foreach
Циклы могут выглядеть плохо, но это короткая версия реальной бизнес-логики в этом методе, которая не имеет отношения к проблеме и пропускается для удобства чтения.
Редактировать: Как оказалось, я должен был получить каждый foreach
значение в качестве ссылки. Это была реальная проблема с кодом, но после внесения указанных изменений он все еще показывает то же поведение (или, если быть более точным, не показывает ожидаемое поведение).
Каждый из ваших foreach
копируют массивы, потому что он имеет несколько ссылок на него. Обсуждение.
Вы можете &
ссылаться на foreach
значения или вы можете добавить ключи, так что в конце вы делаете $this->queue[$i][$j][$k]->content = 'foo';
Рассмотрим эту строку,
public function translate($table, &$results)
Это оценивает Какие изменения применяются к $results
применяются к переменной, переданной этой функции.
Сейчас,
if(!isset($this->queue[$table])) {
$this->queue[$table] = array();
}
$this->queue[$table][] =& $results;
Теперь ничего не сделано для изменения результатов в приведенном выше коде.
Теперь рассмотрим ниже,
public function fetchTranslations()
{
foreach($this->queue as $table) {
foreach($table as $results) {
foreach($results as &$result) {
$result->content = 'DON\'T PANIC THIS IS A TEST';
}
}
}
}
Теперь, вы прошли правильно, по ссылке, но $results
будет меняться в конце концов, а не $this->queue
Если я предлагаю, вам нужно снова построить логику для этого класса