Сначала код, потом проблема

$squad_ids = $mysqli->query("SELECT id FROM squad WHERE owner=$owner_id");

include "squads.php";
$squads = array();
$squads_num = 0;

foreach ($squad_ids as $squad_id){
    $squads[$squads_num] = new Squad($squad_id["id"]);
    var_dump($squads[$squads_num]); // <-------------- DUMP 1
    $squads_num++;
}
...
foreach ($squads as $squad){
    var_dump($squad); // <-------------- DUMP 2
}

Поэтому я заполняю массив $squads объектами Squad (два на тестах). При выгрузке поля массива (DUMP 1) все в порядке, отображаются оба объекта.

После этого я просматриваю созданный массив $squads и хочу получить доступ к сохраненным объектам.

Но по какой-то странной причине это оба раза один и тот же объект. При выгрузке $squad (DUMP 2) он показывает точно то же самое для обеих итераций в тесте (оба раза это вторые объекты).

Я не могу этого объяснить.


(На самом деле между этими двумя циклами foreach есть код ЕСТЬ, но он не имеет ничего общего с $squads.)

Для справки класс:

class Squad {
    private $mysqli;
    private $squad = array(
        "id"=>null,
        "name"=>null,
        "owner"=>null,
        "battlefield"=>null,
        "posx"=>null,
        "posy"=>null,
        "radius"=>null,
        "action"=>null,
        "action_cmd"=>null
        );
    private $map = array();
    private $scan = array();

    function Squad($id){
        global $squad;
        global $mysqli;

        include "db_connect.php";

        $squad_request_raw = $mysqli->query("SELECT * FROM squad WHERE id = '$id'");
        $squad_request = $squad_request_raw->fetch_object();

        $squad["id"] = $squad_request->id;
        $squad["name"] = $squad_request->name;
        $squad["owner"] = $squad_request->owner;
        $squad["battlefield"] = $squad_request->battlefield;
        $squad["posx"] = $squad_request->posx;
        $squad["posy"] = $squad_request->posy;
        $squad["radius"] = $squad_request->radius;
        $squad["action"] = $squad_request->action;
        $squad["action_cmd"] = $squad_request->action_cmd;
    }

    function getId(){
        global $squad;
        return $squad["id"];
    }
}
0
HelloImNewHere 1 Июн 2014 в 02:19
Этот код кажется хорошим на первый взгляд, но многоточие на полпути, кажется, предполагает, что есть что-то еще. Может быть, пропущенный код изменяет массив? Это должно быть.
 – 
GolezTrol
1 Июн 2014 в 02:25
3
 – 
kero
1 Июн 2014 в 02:26
Одна вещь, на которую следует обратить внимание, может вызвать подобные странности, если вы используете какие-либо переменные &$referenced -- с точки зрения &$squads, &squad_id или &$squad в любой момент до к этому коду (или к многоточию) и неправильно unset их перед повторным использованием переменной. Если бы вы могли обновить свой вопрос, указав содержимое $squad_ids, это также было бы полезно при отладке проблемы...
 – 
Pebbl
1 Июн 2014 в 02:36
«На самом деле между этими двумя циклами foreach ЕСТЬ код, но он не имеет ничего общего с $squads» — хорошо, тогда удалите весь этот код — проблема тогда все еще должно сохраняться, если вы правы…
 – 
CBroe
1 Июн 2014 в 02:41
1
Вы должны удалить свои строки global $squad;... они вызывают проблему. Смотрите мой ответ ниже.
 – 
Pebbl
1 Июн 2014 в 03:56

2 ответа

Лучший ответ

Вам обязательно стоит удалить эти строки:

global $squad;

Изнутри вашего класса. В настоящий момент я не могу настроить код для тестирования, но это определенно вызовет странные вещи ... поскольку это тот же самый var, который вы используете в своем foreach и в каждом экземпляре вашего класса. Все глобальные переменные в php работают с самого базового уровня кода, поэтому каждый экземпляр будет использовать одну и ту же переменную ... плюс я не понимаю, почему ваш класс в любом случае требует, чтобы эта переменная была глобальной.

Поскольку вы используете var_dump сразу после создания каждого экземпляра класса в первом цикле, они будут хорошо выглядеть в течение времени жизни каждой итерации цикла. Но поскольку вы глобализируете внутреннюю переменную, используемую вашим классом, каждый раз, когда создается экземпляр, вы будете изменять одну и ту же структуру var /, тем более что вы не переопределяете массив в методе конструктора. Я вообще-то не думаю, что ваш класс вообще будет использовать ваш частный массив $this->squad (хотя он может глобализировать это, я не могу сказать без тестирования) . Бьюсь об заклад, если вы всегда var_dump только первый элемент в массиве - в вашем первом foreach - вы увидите, что он изменяется по ходу цикла. т.е. попробуйте это:

foreach ($squad_ids as $squad_id){
  $squads[$squads_num] = new Squad($squad_id["id"]);
  var_dump($squads[0]); // <-------------- DUMP 1
  $squads_num++;
}

Вы, вероятно, увидите, что $squads[0] станет таким же, как $squads[1] после создания $squads[1], и так далее ... Глобализация переменной $squad фактически заставляет ее действовать то же, что и &reference.

1
Pebbl 1 Июн 2014 в 04:06
Ты мужчина! Я переписал свой класс, используя теперь $this->squad = (); $this->squad["id"] = ...... кажется, работает нормально.
 – 
HelloImNewHere
1 Июн 2014 в 04:13
~ не беспокойтесь, рад, что смог помочь. Справочные проблемы всегда будут вызывать у вас небольшое помешательство, поскольку кажется, что происходит волшебство :)
 – 
Pebbl
1 Июн 2014 в 11:38

Я не вижу проблем в вашем коде, но я бы также попытался установить ключ в вашем цикле и посмотреть, что было напечатано:

foreach ($squads as $key => $squad){
    var_dump($squads[$key]); 
}
0
Teknotica 1 Июн 2014 в 02:30