& Quot; Binding & Quot; переменные по ссылке для отложенной обработки в классе

У меня есть синглтон следующего класса. Я пытаюсь добиться сбора ссылок на различные массивы результатов базы данных, которые вызываются по всему приложению, а затем, наконец, сделать один запрос к базе данных и получить некоторые замещающие значения (переводы) вместо того, чтобы делать это для каждого отдельного запроса.

Оставляя в стороне плюсы и минусы этого подхода, я не могу сделать фактическую замену «исходных» значений (результатов базы данных), которые передаются в 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 значение в качестве ссылки. Это была реальная проблема с кодом, но после внесения указанных изменений он все еще показывает то же поведение (или, если быть более точным, не показывает ожидаемое поведение).

2

Решение

Каждый из ваших foreach копируют массивы, потому что он имеет несколько ссылок на него. Обсуждение.

Вы можете & ссылаться на foreach значения или вы можете добавить ключи, так что в конце вы делаете $this->queue[$i][$j][$k]->content = 'foo';

1

Другие решения

Рассмотрим эту строку,

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

Если я предлагаю, вам нужно снова построить логику для этого класса

0