Форум программистов, компьютерный форум, киберфорум
PHP
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 22.01.2023
Сообщений: 11

Спец. методы __sleep() и __wakeup()

31.01.2023, 01:01. Показов 626. Ответов 3
Метки php (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Столкнулся с проблемой: при попытке создания скрипта для сериализации и восстановления объекта класса с помощью спец. методов __sleep() и __wakeup почему-то переменная $key внутри класса(необходимая для объявления переменной с другим ключом в массиве) существует только внутри метода __set(). После подстановки __sleep() внутрь метода __set() сериализировать элемент 'key' получилось. Но вот восстановить уже не получается.
Если коротко: каким образом происходит сериализация и десериализация элементов массива при использовании спец. методов __set() и __get() для присвоения значения переменной из другого файла. Возможно, я чего-то не понимаю, но найти информацию в интернете не удалось.
Также, почему, если __sleep() находится вне метода __set() он не работает и выдает ошибку с ненайденной переменной $key

1) Основной скрипт с классом и методами
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
<?php
class Accessor
{
    private $array = [];
    private $link;
    
    public function __get($key)
    {
        if(array_key_exists($key, $this->array)) {
            return $this->array[$key];
        } else {
            return null;
        }
    }
 
    public function __set($key, $value)
    {
        $this->array[$key] = $value;
        function __sleep(){
            return array('key');
        }
        function connect()
            {
                $this->link = array('key');
            }
        function __wakeup()
            {
                $this->link = $this->connect();
            }
    }
    
}
2) Второй скрипт, для работы с объектами класса из первого
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
require_once 'accessor.php';
 
$obj = new Accessor();
 
$obj->name = 'Hello, world!<br />';
echo $obj->name;
 
echo serialize($obj) . "<br />";
 
echo "<pre>";
print_r($obj);
echo "</pre>";
 
unserialize($obj);
print_r($obj);
Буду рад любой информации по данной теме. Спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.01.2023, 01:01
Ответы с готовыми решениями:

Auto-wakeup (AWU)
Почему работает с включенным HSI (LSI отключен),хотя по мануалу должен от HSE или LSI? Переключался на LSI CLK_CMSR стало = 0xD2 ,HSI не...

конфигурация и запуск RTC WakeUp Timer
Добрый день. Использую RTC WakeUp Timer для stm32, но не получается его сконфигурировать. RTC настроен и работает. WakeUpTimer настраиваю...

Компромис скорости и нагрузки на процессор - Thread.Sleep(0) и Thread.Sleep(1)
Всем привет! Есть бесконечный цикл. while(true) { ... } Внутри выполняются важные операции)

3
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
31.01.2023, 02:34
Цитата Сообщение от MrGreatFish Посмотреть сообщение
почему-то переменная $key внутри класса
В данном классе нет переменной свойства $key, есть только $array и $link

Цитата Сообщение от MrGreatFish Посмотреть сообщение
После подстановки __sleep() внутрь метода __set()
В классе больше нет метода __sleep, зато есть глобальная функция __sleep

Цитата Сообщение от MrGreatFish Посмотреть сообщение
почему, если __sleep() находится вне метода __set() он не работает и выдает ошибку с ненайденной переменной $key
Потому что переменной свойства $key нет. Сериализации подвергаются реальные свойства.

Наводящий вопрос: что возвращает метод connect, и что будет в $this->link?
Цитата Сообщение от MrGreatFish Посмотреть сообщение
PHP
1
2
3
4
5
6
7
8
function connect()
{
    $this->link = array('key');
}
function __wakeup()
{
    $this->link = $this->connect();
}

И всё отлично работает https://onlinephp.io/c/4bcb5
Кликните здесь для просмотра всего текста
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
<?php
// Enter your code here, enjoy!
class Accessor
{
    private $array = [];
    private $link;
    
    public function __get($key)
    {
        return $this->array[$key] ?? null;
    }
 
    public function __set($key, $value)
    {
        $this->array[$key] = $value;
    }
    public function __sleep(){
        return ['array'];
    }
    public function connect()
    {
        $this->link = ['key'];
    }
    public function __wakeup()
    {
        $this->connect();
    }
}
    
$a = new Accessor();
$a->key = 42;
$a->connect();
$str = serialize($a);
var_dump($a, $a->key, $str);
 
echo "--------------------------\n";
 
$b = unserialize($str);
var_dump($b);
0
0 / 0 / 0
Регистрация: 22.01.2023
Сообщений: 11
31.01.2023, 12:35  [ТС]
Спасибо за ответ, многие ошибки понял. Но: насколько я знаю(понимаю), методы __sleep() и __wakeup() необходимы, чтобы сериализировать и десериализировать только определенные элементы массива, а не весь массив целиком. В вашем коде как раз таки происходит полная сериализация:
PHP
1
2
3
public function __sleep(){
        return ['array'];
    }
И десериализация тоже полная, несмотря на ключ 'key' в методе connect()
Отвечаю на наводящий вопрос: исходя из того, что написано на php.net про магические методы, я пришел к выводу, что в __wakeup() мы должны ссылаться на connect(), в котором и лежат ключи необходимых элементов массива.
Скорее всего я в чем-то ошибаюсь, поправьте, пожалуйста.
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
31.01.2023, 15:07
Лучший ответ Сообщение было отмечено MrGreatFish как решение

Решение

Цитата Сообщение от MrGreatFish Посмотреть сообщение
методы __sleep() и __wakeup() необходимы, чтобы сериализировать и десериализировать только определенные элементы массива, а не весь массив целиком
Не массива, а объекта от некоторого класса.
Цитата Сообщение от MrGreatFish Посмотреть сообщение
В вашем коде как раз таки происходит полная сериализация
У объекта класса Accessor 2 свойства, я указываю серриализовать одно. Содержимое свойства $array сериализуется полностью. Если хочется не полностью, значит надо лишение свойства удалить. Но так лучше не делать, не стоит при сериализации портить исходный объект, тут пара методов __seizalize, __unserialize лучше подойдёт.

Цитата Сообщение от MrGreatFish Посмотреть сообщение
И десериализация тоже полная, несмотря на ключ 'key' в методе connect()
Одно из двух свойств восстанавливается в методе __wakeup

Цитата Сообщение от MrGreatFish Посмотреть сообщение
Отвечаю на наводящий вопрос: исходя из того, что написано на php.net про магические методы, я пришел к выводу, что в __wakeup() мы должны ссылаться на connect(), в котором и лежат ключи необходимых элементов массива.
Вопрос вообще не про это был.
Цитата Сообщение от MrGreatFish Посмотреть сообщение
PHP
1
2
3
4
5
6
7
8
function connect()
{
    $this->link = array('key');
}
function __wakeup()
{
    $this->link = $this->connect();
}
Сначала будет вызван __wakeup, внутри __wakeup будет вызван connect. Внутри connect в свойство $link будет записано ['key']. Потом метод __wakeup продолжит выполнение, и запишет в свойство $link то, что вернул connect. А в методе connect нет ни одного return, значит вернёт null.
Именно поэтому
Цитата Сообщение от MrGreatFish Посмотреть сообщение
Но вот восстановить уже не получается.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.01.2023, 15:07
Помогаю со студенческими работами здесь

Методы приближенного дифференцирования + Методы сплайновой интерполяции функций v2.0
Народ нужна помощь, может для кого то банальные вопросы но для меня с моеи математикой все плохо. Методи наближеного диференціювання: ...

Методы LINQ (язык запросов) или методы расширения?
Методы LINQ (язык запросов) можно сочетать с методами расширения для (объектов) интерфейса IEnumerable, которые представлены методами...

Методы приближенного дифференцирования + Методы сплайновой интерполяции функций v2.0
https://www.cyberforum.ru/mathcad/thread568259.html#post3002923 Помогите пожалуйста, ссылка выше мое задание в маткаде, их нужно...

Разработать классы для описанных ниже объектов. Включить в класс методы set (…), get (…), show (…). Определить другие методы
Разработать классы для описанных ниже объектов. Включить в класс методы set (…), get (…), show (…). Определить другие методы Abiturient:...

Ищу спец-а по ИИ
Здравствуйте, Вакансия с неполной занятостью, несколько часов в неделю, подработка. Создание ИИ (или поиск готовой нейросети) и...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru