461 / 369 / 94
Регистрация: 01.05.2010
Сообщений: 1,761
1

Перезаписывается параметр по умолчанию и статическая переменная

26.04.2019, 11:44. Показов 863. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет! Столкнулся с очень непонятной ситуацией. Может все очевидно, но... что-то я совсем не могу понять...
Итак есть объект локации (ObservePoint) и объект, который сохраняет массив таких локаций в json файл. Все отлично работало, пока я не решил добавить идентификатор к локациям. Смысл в том, что у локаций не может быть два одинаковых идентификатора. Если идентификатор явно не передавать конструктору, то конструктор должен сам его добавлять.

Вот клиентский код:
PHP
1
2
3
4
5
6
7
8
9
10
use fop2019\ObservePoint;
use fop2019\ObservePointSaverJSON;
 
define('HALASTRO_THEME_DIR', __DIR__);
define('OBSERVE_POINTS_PATH', HALASTRO_THEME_DIR.DIRECTORY_SEPARATOR.'observe_points.json');
// ...
$ps = new ObservePointSaverJSON(HALASTRO_THEME_DIR."/observe_points.json");
$ps->add(new ObservePoint('Test location 1', 50.005, 30.008, "Just for tests at 1"));
$ps->add(new ObservePoint('Test location 2', -50.005, 38.008, "Another just testing"));
$ps->save();
Сразу же бросается исключение на первой строке $ps->add():
Код
Index 1 is alresy in use. Index should be unique integer
Когда присваивается индекс, то проверяется статическое свойство, хранящее все присвоенные индексы. Проверка происходит до того, как в это свойство (массив) заносится присвоенный индекс. Но каким-то образом этот индекс уже там...
И еще странность. В конструкторе класса ObservePoint указан параметр $id = 0. Но почему-то он перезаписывается 1, хотя я этот параметр не передаю! Как так получается?
Спасибо за разъяснения...

ObservePoint
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
namespace fop2019;
 
class ObservePoint {
    private static $indexes = [];
 
    private $id;
    private $name;
    private $latitude;
    private $longitude;
    private $description;
 
    public function __construct(string $name, float $latitude, float $longitude, string $description = "", int $id = 0) {
        var_dump(self::$indexes);
        var_dump($id);
        if ($id <= 0) {
            $id = self::getNextId();
            //var_dump($id);
        }
        $this->id = $id;
        $this->name = $name;
        $this->latitude = $latitude;
        $this->longitude = $longitude;
        $this->description = $description;
 
        self::pushIndex($id);
    }
 
    public function getId() : int {
        return $this->id;
    }
 
    public function getName() : string {
        return $this->name;
    }
 
    public function getLatitude() : float {
        return $this->latitude;
    }
 
    public function getLongitude() : float {
        return $this->longitude;
    }
 
    public function getDescription() : string {
        return $this->description;
    }
 
    private static function getNextId() : int {
        if (!count(self::$indexes)) {
            return 1;
        }
 
        return max(self::$indexes) + 1;
    }
 
    /** Check unique id of each point. Throws Exception if id is not unique.
    */
    private static function pushIndex(int $id) : int {
        if (in_array($id, self::$indexes)) {
            throw new \Exception("Index ".$id." is alresy in use. Index should be unique integer.");
        }
        self::$indexes[] = $id;
        return count(self::$indexes);
    }
}
ObservePointSaver
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace fop2019;
 
abstract class ObservePointSaver {
    private $points = [];
 
    public function add(ObservePoint $point) {
        $this->points[] = $point;
    }
 
    public function setPoints(array $points) {
        foreach ($points as $point) {
            if (!($point instanceof ObservePoint)) {
                throw new \Exception("Elements in array should be instances of ObservePoint class.");
            }
            $this->points = $points;
        }
    }
 
    public function getPoints() : array {
        return $this->points;
    }
 
    abstract public function save();
}
ObservePointSaverJSON
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace fop2019;
 
class ObservePointSaverJSON extends ObservePointSaver {
    private $path;
 
    public function __construct(string $path) {
        $this->path = $path;
    }
 
    public function save() {
        $out = [];
        foreach ($this->getPoints() as $point) {
            $out[] = [
                'id' => $point->getId(),
                'name' => $point->getName(),
                'latitude' => $point->getLatitude(),
                'longitude' => $point->getLongitude(),
                'description' => $point->getDescription()
            ];
        }
 
        file_put_contents($this->path, json_encode($out));
    }
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.04.2019, 11:44
Ответы с готовыми решениями:

Модульная переменная или блочная статическая переменная: что лучше
Переменная (тип String) нужна на всем протяжении работы программы. Нужен совет опытных - что...

Статическая переменная
Всем привет! :) Совсем недавно только начал изучать C++, ранее все писал на C#. Я хочу через...

Статическая переменная
&lt;html&gt;&lt;body&gt; &lt;?php function selfcount() { static $count = 0; $count++; echo $count; }...

Статическая переменная
Добрый день! Объясните пожалуйста, что такое статическая переменная, в каких случаях лучше...

2
Эксперт PHP
3851 / 3196 / 1343
Регистрация: 01.08.2012
Сообщений: 10,820
26.04.2019, 12:27 2
У меня код работает. Вызываю add 5 раз, ошибки нет, если не передаю id вручную. Это точно весь код?

Цитата Сообщение от Зверушь Посмотреть сообщение
Как так получается?
Так вы же getNextId вызываете, он и возвращает единицу.
1
461 / 369 / 94
Регистрация: 01.05.2010
Сообщений: 1,761
26.04.2019, 12:47  [ТС] 3
Цитата Сообщение от Jodah Посмотреть сообщение
Так вы же getNextId вызываете, он и возвращает единицу.
Я getNextId() вызывал после var_dump().

Цитата Сообщение от Jodah Посмотреть сообщение
У меня код работает. Вызываю add 5 раз, ошибки нет, если не передаю id вручную. Это точно весь код?
Не весь... Весь код намного больше. Блин, вот я дурень.... я только что нашел причину... Кроме класса ObservePointSaverJSON у меня есть еще ObservePointLoaderJSON... про который я забыл... И вот тут то и возник конфликт. Я то когда сохраняю новую локацию, то ее id остается в массиве индексов... И потом при загрузке из файла загрузчик не может создать локацию с таким id... придется решать эту проблему... Спасибо...
0
26.04.2019, 12:47
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.04.2019, 12:47
Помогаю со студенческими работами здесь

Статическая переменная?
Мне надо в lua функции определить переменную с поведением static, как в C++. Как это можно...

Объекты: параметр-значение и параметр-переменная
Если сделать код таким: type TPos=object ax,ay:integer; constructor...

Статическая переменная в delphi
Здравствуйте! Не подскажете есть ли в делфи статическая переменная как в С++. У которой время жизни...

Статическая переменная в шаблоне
// // (---.Array_hpp---) // #ifndef Array_HPP // Preprocessor gates...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru