Магические функции __sleep и __wakeup


Содержание

Магические функции __sleep и __wakeup

Имена методов __construct, __destruct (см. Конструкторы и деструкторы), __call, __callStatic, __get, __set, __isset, __unset (см. Перегрузка), __sleep, __wakeup, __toString, __set_state и __clone зарезервированы для «магических» методов в PHP. Не стоит называть свои методы этими именами, если вы не хотите использовать их «магическую» функциональность.

PHP оставляет за собой право все методы, начинающиеся с __, считать «магическими». Не рекомендуется использовать имена методов с __ в PHP, если вы не желаете использовать соответствующий «магический» функционал.

__sleep и __wakeup

Функция serialize() проверяет, присутствует ли в вашем классе метод с «магическим» именем __sleep. Если это так, то этот метод выполняется прежде любой операции сериализации. Он может очистить объект и предполагается, что будет возвращен массив с именами всех переменных объекта, который должен быть сериализован. Если метод ничего не возвращает кроме NULL, то это значит, что объект сериализован и выдается предупреждение E_NOTICE.

Обычно __sleep используется для передачи ожидаемых данных или для выполнения обычных задач их очистки. Также, этот метод можно выполнять в тех случаях, когда вы не хотите сохранять очень большие объекты полностью.

С другой стороны, функция unserialize() проверяет наличие метода с «магическим» именем __wakeup. Если такой имеется, то он может воссоздать все ресурсы объекта, которые тот имеет.

Обычно __wakeup используется для восстановления любых соединений с базой данных, которые могли быть потеряны во время операции сериализации и выполнения других операций повторной инициализации.

Пример #1 Sleep и wakeup

class Connection <
protected $link ;
private $server , $username , $password , $db ;

public function __construct ( $server , $username , $password , $db )
<
$this -> server = $server ;
$this -> username = $username ;
$this -> password = $password ;
$this -> db = $db ;
$this -> connect ();
>

private function connect ()
<
$this -> link = mysql_connect ( $this -> server , $this -> username , $this -> password );
mysql_select_db ( $this -> db , $this -> link );
>

public function __sleep ()
<
return array( ‘server’ , ‘username’ , ‘password’ , ‘db’ );
>

public function __wakeup ()
<
$this -> connect ();
>
>
?>

__toString

Метод __toString позволяет классу решать самостоятельно, как он должен реагировать при преобразовании в строку.

Пример #2 Простой пример

// Декларирование простого класса
class TestClass
<
public $foo ;

public function __construct ( $foo ) <
$this -> foo = $foo ;
>

public function __toString () <
return $this -> foo ;
>
>

$class = new TestClass ( ‘Привет’ );
echo $class ;
?>

Результат выполнения данного примера:

Ранее, до PHP 5.2.0, метод __toString вызывался только непосредственно в сочетании с функциями echo() или print() . Начиная с PHP 5.2.0, он вызывается в любом строчном контексте (например, в printf() с модификатором %s), но не в контекстах других типов (например, с %d модификатором). Начиная с PHP 5.2.0, преобразование объекта в строку при отсутствии метода __toString вызывает ошибку E_RECOVERABLE_ERROR.

__invoke

The __invoke method is called when a script tries to call an object as a function.

Использование магических методов PHP __sleep и __wakeup

Что такое использование методов __sleep и __wakeup magic в PHP? Я прочитал документацию по PHP, но до сих пор неясно:

Этот пример кода печатает:

Если бы я переименовал __sleep и __wakeup в foo и bar то он сделает то же самое. Каково надлежащее использование этих двух методов?

Как уже описано, __sleep() вызывается, когда вы serialize() объект и __wakeup() после того, как вы unserialize() его.

Сериализация используется для сохранения объектов: вы получите представление объекта в виде строки, которая затем может быть сохранена в $_SESSION , базе данных, кукисах или в любом другом месте, которое вы хотите.

Значения ресурсов


Однако serialize() не может сериализовать (т. Е. Преобразовать в текстовое представление) значение sof типа ресурса . Вот почему все эти значения unserialize() после unserialize() .

График объектов

или членов, и членов членов, и … ad infinitum

Другой, возможно, более важный момент в том, что serialize() будет пересекать весь граф объектов $obj если вы его сериализуете. Это здорово, когда вам это нужно, но если вам нужны только части объекта, а определенные связанные объекты «зависят от времени выполнения» и распределяются между множеством объектов, но и другими объектами, вы можете не хотеть этого поведения.

PHP правильно обрабатывает циклические графики! Значение: Если (член) $ ссылки на $ b, а ссылки $ b на $ a обрабатываются правильно, но многие уровни глубоки.

Пример – связанные с сеансом (общие) объекты

Например, объект $database ссылается на $obj->db , но также и на другие объекты. Вы хотите, чтобы $obj->db были теми же объектами – после unserialize() ing – что все остальные объекты в вашем следующем сеансе имеют не изолированный экземпляр объекта базы данных.

В этом случае у вас будет метод __sleep() например:

и затем восстановить его следующим образом:

Другая возможность заключается в том, что объект является частью некоторой (глобальной) структуры данных, где ее необходимо зарегистрировать. Конечно, вы можете сделать это вручную:

Однако, если это часть контракта с объектами, что он должен быть в этом реестре, не рекомендуется оставлять этот магический вызов пользователю вашего объекта. Идеальное решение, если объект заботится о своих обязанностях, т.е. регистрируется в Thing . Это то, что __wakeup() позволяет вам делать прозрачно (т. __wakeup() Больше не беспокоится об этой магической зависимости) для вашего клиента.

Аналогичным образом вы можете использовать __sleep() для « __sleep() » объекта, если это необходимо. (Объекты не уничтожаются, когда они сериализованы, но это может иметь смысл в вашем контексте.)

Затворы

И последнее, но не менее важное: закрытие также не поддерживает сериализацию. Это означает, что вам нужно будет воссоздать все прикрепленные закрытия в __wakeup() .

Эти методы используются при вызове serialize () и unserialize () на объектах, чтобы убедиться, что у вас есть крючок, чтобы удалить некоторые свойства, такие как соединения с базой данных, и установить их при загрузке. Это происходит при хранении объектов в сеансах между прочим.

Они в значительной степени похожи на функции крюка, которые мы можем использовать в соответствии с нашими потребностями. Я придумал этот простой пример в реальном времени. Теперь попробуйте выполнить этот код в двух сценариях

Сценарий 1:
Сначала, комментируя метод __sleep () и __wakeup (), проверьте вывод. Вы обнаружите, что ресурс отсутствует, когда вы несериализуете его.

Сценарий 2:
Теперь попробуйте запустить его, раскомментируя их, вы поймете, что объект, сбрасываемый в первом и последнем var_dump, будет таким же.

Использование магических методов PHP __sleep и __wakeup — oop

Каково использование магических методов __sleep и __wakeup в PHP? Я прочитал документацию PHP, но все еще неясно:

Этот пример кода печатает:

Если бы я переименовал __sleep и __wakeup в foo и bar , тогда он сделает то же самое. Каково надлежащее использование этих двух методов?

    4 4
  • 6 окт 2020 2020-10-06 15:54:36
  • Madan Sapkota

4 ответа

  • 6 окт 2020 2020-10-06 15:54:37
  • donald123

Они в значительной степени похожи на функции крюка, которые мы можем использовать в соответствии с нашими потребностями. Я придумал этот простой пример в реальном времени. Теперь попробуйте выполнить этот код в двух сценариях

Сценарий 1:
Сначала, комментируя метод __sleep() и __wakeup(), проверьте вывод. Вы потеряете ресурс, если вы несериализуете его.

Сценарий 2:
Теперь попробуйте запустить его, раскомментируя их, вы поймете, что объект, сбрасываемый в первом и последнем var_dump, будет таким же.

  • 6 окт 2020 2020-10-06 15:54:37
  • Mohammed Asad

Эти методы используются при вызове serialize() и unserialize() для объектов, чтобы убедиться, что у вас есть крючок для удаления некоторых свойств, таких как соединения с базой данных, и их возврата при загрузке. Это происходит при хранении объектов в сеансах между прочим.

  • 6 окт 2020 2020-10-06 15:54:37
  • Louis-Philippe Huberdeau

Как уже описано, __sleep() вызывается, когда вы serialize() объект и __wakeup() после unserialize() it.

Сериализация используется для сохранения объектов: вы получите представление объекта в виде строки, которая затем может быть сохранена в $_SESSION , базе данных, файлах cookie или в любом другом месте, которое вы хотите.

Значения ресурсов

Однако serialize() не может сериализовать (т.е. преобразовать в текстовое представление) значение с помощью типа ресурса. Вот почему все эти значения исчезнут после unserialize() .

График объектов

или членов, а также членов-членов и. ad infinitum

Другим, возможно, более важным является то, что serialize() будет пересекать весь граф объекта $obj , если вы его сериализуете. Это здорово, когда вам это нужно, но если вам нужны только части объекта, а определенные связанные объекты являются «специфичными для выполнения» и распределяются между множеством объектов, но и другими объектами, вы можете не хотеть этого поведения.

PHP правильно обрабатывает циклические графики! Значение: If (член) $ссылки на $b, а ссылки $b на $a обрабатываются правильно, но на многих уровнях.

Пример — объекты, специфичные для сеанса (общие)

Например, объект $database ссылается на $obj->db , но также на другие объекты. Вы хотите, чтобы $obj->db были теми же объектами — после unserialize() ing — все остальные объекты в следующем сеансе, а не изолированный экземпляр объекта базы данных.

В этом случае у вас будет метод __sleep() , например:

а затем восстановить его следующим образом:

Другая возможность заключается в том, что объект является частью некоторой (глобальной) структуры данных, где он должен быть зарегистрирован. Вы можете сделать это вручную, конечно:

Однако, если это часть контракта с объектами, что он должен быть в этом реестре, не рекомендуется оставлять этот магический вызов пользователю вашего объекта. Идеальное решение заключается в том, что объект заботится об этом, то есть регистрируется в Thing . То, что __wakeup() позволяет вам прозрачно (т.е. Больше не беспокоиться об этой магической зависимости) для вашего клиента.

Аналогичным образом вы можете использовать __sleep() для «деинсталляции» объекта, если это необходимо. (Объекты не уничтожаются, когда они сериализованы, но это может иметь смысл в вашем контексте.)

Затворы

И последнее, но не менее важное: закрытие делает не сериализацию поддержки. Это означает, что вам нужно будет воссоздать все прикрепленные закрытия в __wakeup() .

Магические методы в PHP


Здравствуйте! В этой статье я расскажу Вам о магических методах в PHP. Они позволяют программисту получить больший контроль над кодом, который будет исполняться, или же добавляют так называемый «синтаксический сахар», вследствие чего код можно писать яснее и чище.

Магические методы в PHP – это методы, которые начинаются с двойного подчеркивания, поэтому, согласно официальной документации по языку PHP, будьте бдительны, если намереваетесь использовать двойное подчеркивание, так как интерпретатор языка оставляет за собой право все методы, начинающиеся с двойного подчеркивания считать «магическими».

Итак, вот список этих методов:

Теперь подробнее о каждом методе.

__construct, __destruct

Эти методы вызываются автоматически при создании и уничтожении объекта. Метод __construct вызывается при создании объекта некоторого класса, а метод __destruct – при уничтожении этого объект. Метод __destruct в PHP используется редко, ввиду небольшого срока жизни скрипта.

__call, __callStatic

Эти два метода используются для одного и того же – для вызова методов, которые не созданы программистом в классе явно. Метод __call применяется для вызова несуществующих методов в контексте объекта, т.е. для вызова методов объекта. Метод __callStatic применяется для вызова методов в контексте класса, т.е. для вызова статических методов. Оба метода принимают в качестве параметров два аргумента: первый — $name – имя фиктивного метода, которое является регистрозависимым, т.е. $obj->method() и $obj -> Method() – будут разные методы, второй $arguments – массив аргументов метода:

objMethod(«метод объекта»);
MyClass::objMethod(«метод класса»);

__get, __set

Эти магические методы выполняют функцию установки и получения значения поля класса, которого не существует, т.е. с помощью них происходит обращение к несуществующим свойствам объекта. Пример:

name = «Супер-класс»;
print $obj -> name;

__sleep, __wakeup

Применяются при сериализации объекта. Не буду останавливаться на этом, так как на сайте уже есть подробная статья об этих методах.

__toString

Этот метод Вы можете использовать тогда, когда хотите, чтобы объект мог быть свободно преобразован в строку. Обратите внимание, что метод обязательно должен возвращать строку, иначе интерпретатор выдаст ошибку. Пример:

__invoke

Этот метод используется для того, чтобы вызвать объект класса как функцию. Пример:

Таким вот образом, теперь Вы знаете, что магические методы PHP могут использоваться там, где нужна функциональность, которую неудобно реализовывать стандартными средствами. А как Вы будете использовать их зависит только от Ваших потребностей .

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Она выглядит вот так:

  • BB-код ссылки для форумов (например, можете поставить её в подписи):
  • Комментарии ( 0 ):

    Для добавления комментариев надо войти в систему.
    Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.


    Copyright © 2010-2020 Русаков Михаил Юрьевич. Все права защищены.

    Использование методов PHP Magic sleep и wakeup

    какая польза от __sleep и __wakeup магические методы в PHP? Я читал документацию PHP, но это все еще не ясно:

    этот код выводит:

    если бы я переименовал __sleep и __wakeup to foo и bar затем он делает то же самое. Как правильно использовать эти два метода?

    4 ответов

    как уже говорилось, __sleep() вызывается, когда вы serialize() объект и __wakeup() после unserialize() его.

    сериализация используется для сохранения объектов: вы получите представление объекта в виде строки, которая затем может быть сохранена в $_SESSION , база данных, куки или где-нибудь еще вы хотите.

    значения ресурсов

    объект графе

    или члены, а члены члена и то . ad infinitum

    другой, возможно, более важный момент, что serialize() будет проходить весь граф объекта $obj если вы сериализовать его. Это здорово, когда вам это нужно, но если вам нужны только части объекта и некоторые связанные объекты «специфичны для среды выполнения» и совместно используются многими объектами, но и другими объектами, вы можете не хотеть такого поведения.

    PHP правильно обрабатывает циклические графики! Значение: если (член) $a ссылается на $b,А $b ссылки на $a обрабатываются правильно, сколько бы уровней ни было.

    пример-конкретные (общие) объекты сеанса

    например, a $database «объект», на который ссылается $obj->db , но и другими объектами. Вы хотите $obj->db быть теми же объектами-после unserialize() ing-что все остальные объекты в следующем сеансе имеют, а не изолированный экземпляр объекта базы данных.

    в этом случае, вы бы __sleep() метод, такой как этот:

    а затем восстановить его следующим образом:

    другая возможность заключается в том, что объект является частью некоторой (глобальной) структуры данных, где он должен быть зарегистрирован. Вы можете сделать это вручную курс:

    однако, если это часть контракта объектов, который он должен быть в этом реестре, не рекомендуется оставлять этот магический вызов пользователю вашего объекта. Идеальным решением является, если объект заботится о своих обязанностях, т. е. регистрируется в Thing . Вот что!—5 позволяет вам делать прозрачно (т. е. ему больше не нужно беспокоиться об этой магической зависимости) для вашего клиента.

    аналогично, вы можете использовать __sleep() в «un-register» объект, если это необходимо. (Объекты не уничтожаются при сериализации, но это может иметь смысл в вашем контексте.)

    закрытие

    последнее, но не менее важное, закрытиене поддержка сериализации либо. Это означает, что вам придется повторно создать все прикрепленные закрытия в __wakeup() .

    эти методы используются при вызове serialize() и unserialize () на объектах, чтобы убедиться, что у вас есть крюк, чтобы удалить некоторые свойства, такие как подключения к базе данных, и установить их обратно при загрузке. Это происходит, в частности, при хранении объектов в сеансах.

    они довольно много как функции крюка, которые мы можем использовать согласно нашим потребностям. Я придумал этот простой пример в реальном времени. Теперь попробуйте выполнить этот код в двух сценариях:

    первый в комментариях __sleep() и __wakeup() методы, проверьте выход. Вы найдете ресурс отсутствует, когда вы unserialize его.

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

    Использование PHP Магические методы __sleep и __wakeup

    November 2020

    18.3k раз

    Что такое использование __sleep и __wakeup магических методов в PHP? Я прочитал документацию PHP , но это все еще не ясно:

    Этот пример кода печатает:


    Если бы я переименовать __sleep и __wakeup к foo а bar затем он делает то же самое. Что такое правильное использование этих двух методов?

    4 ответы

    Они довольно много, как крючки функция, которые мы можем использовать в соответствии с нашими потребностями. Я придумал этот простой пример реального времени. Теперь попробуйте запустить этот код в двух случаях:

    Во- первых, комментируя __sleep() и __wakeup() методы, проверьте вывод. Вы найдете ресурс отсутствующий , когда вы десериализируетесь его.

    Теперь попробуйте запустить его раскомментировать их, вы будете выяснить , что объект сбрасывали в первый и последний var_dump будет то же самое.

    Эти методы используются при вызове Serialize () и десериализаций () на объектах, чтобы убедиться, что у вас есть крюк, чтобы удалить некоторые свойства, как соединения с базой данных и установить их обратно при загрузке. Это происходит при сохранении объектов в сеансах среди других вещей.

    Как уже было описано выше, __sleep() называется , когда вы serialize() объекта и __wakeup() после того, как вы unserialize() его.

    Сериализация используется для сохранения объектов: Вы получите представление объекта в виде строки , которые затем могут быть сохранены в $_SESSION , базы данных, печенье или в другом месте вы хотите.

    значения ресурсов

    Тем не менее, serialize() не может сериализовать (т.е. преобразование в текстовом представлении) значение СОФ в типе ресурса . Именно поэтому все эти значения будут пропадают после unserialize() ИНГ его.

    график объекта

    или члены и члены пользователя и . до бесконечности

    Другой, возможно , более важным моментом является то , что serialize() будет проходить весь объект график , $obj если вы сериализовать его. Это очень удобно , когда вам это нужно, но если вам нужно только части объекта и некоторые связанные объекты являются « во время выполнения конкретных» и общим для многих объектов , но и другими объектами, вы не хотите этого поведения.

    PHP обрабатывает циклические графы правильно! Значение: Если (член) $ а ссылки на $ Ь и $ B ссылки на $ а обрабатываются корректно, однако много уровней в глубину.

    Пример — сеанс специфический (общие) объекты

    Например, $database объект ссылается $obj->db , но и другими объектами. Вы хотите , $obj->db чтобы одни и те же объекты — после unserialize() ИНГ — что все остальные объекты в вашей следующей сессии есть, не изолированный экземпляр объекта базы данных.

    В этом случае, вы бы __sleep() метод, как это:

    а затем восстановить его, как это:

    Другая возможность заключается в том, что объект является частью некоторых (глобальных) структуры данных, где он должен быть зарегистрирован. Вы можете сделать это вручную, конечно:

    Однако, если она является частью контракта объектов , что он должен быть в этом реестре, это не очень хорошая идея , чтобы оставить этот волшебный призыв к пользователю вашего объекта. Идеальное решение, если объект заботится о его ответственности, т.е. будучи зарегистрированным в Thing . Это то, что __wakeup() позволяет делать прозрачно (то есть ему нужно больше не беспокоиться о том , что магической зависимости) к вашему клиенту.

    Кроме того , вы можете использовать , __sleep() чтобы «отменить регистрацию» объект , если это необходимо. (Объекты не разрушаются , когда они сериализации, но это может иметь смысл в вашем контексте.)

    Затворы

    И последнее , но не в последнюю очередь, замыкания которых не поддерживают сериализацию либо. Это означает , что вам придется заново создавать все подключенные к нему замыканию в __wakeup() .

    Разница между fall asleep и nod, wake up и get up, wake и awake

    Давайте признаемся себе: мы все очень любим спать. Наверно, поэтому в нашем языке так много устойчивых выражений на эту тему — спать без задних ног, засыпать, дремать, кемарить, вырубаться, проваливаться в сон — но так мало слов о пробуждении, которое лишает нас сладкого сна. В английском языке похожая ситуация. Сегодня узнаем устойчивые выражения и фразовые глаголы со словом sleep, а также разберемся в отличиях глаголов fall asleep, nap и crash out, рассмотрим разницу между wake up и get up, wake и awake.

    Глагол to sleep

    Глагол sleep переводится как «спать».

    When I was a child I slept badly at night. — Когда я была ребенком, я плохо спала по ночам.

    Еще одно значение глагола sleep — вмещать, оно встречается в описаниях отелей и гостевых домов.

    Our hostel room sleeps eight people. — Наша комната в хостеле вмещает восемь человек.

    С этим глаголом существует множество выражений и идиом, представим самые распространенные из них:


    Словосочетание Перевод
    a sleepover ночевка у кого-то; пижамная вечеринка
    to sleep well, to sleep soundly хорошо спать
    to sleep uneasily тревожно спать
    to sleep like a log, to sleep like a baby спать как убитый
    to sleep the night переночевать у кого-то
    to sing smb to sleep убаюкать кого-то
    to put smb to sleep, to send smb to sleep уложить кого-то спать
    to oversleep, to sleep late проспать
    beauty sleep сон, который позволяет оставаться здоровым и хорошо выглядеть
    let sleeping dogs lie не буди лихо, пока тихо
    Sleep tight! Спи крепко!
    Словосочетание Перевод
    to sleep in спать дольше обычного, отсыпаться
    to sleep on переспать с проблемой, отложить до следующего дня (утро вечера мудренее)
    to sleep over переночевать у кого-то, остаться с ночевкой
    to sleep through спать, несмотря на шум и помехи
    to sleep through until/to спать до какого-то времени

    В неформальном американском английском есть выражения, которые тоже переводятся как «спать»: to catch some z’s, to cop some z’s, to get some z’s. В комиксах вы можете встретить персонажа с буквами zzz над головой .

    Бывает, что человек страдает бессонницей (insomnia), с этим явлением связано несколько понятий:

    Слово/Словосочетание Перевод
    sleepless бессонный, без сна
    not sleep a wink не сомкнуть глаз
    to lose sleep over smth потерять сон из-за чего-либо

    2. To fall asleep, to nap, to crash out и другие фразовые глаголы

    To fall asleep или to go to sleep переводятся как «засыпать».

    I’m on my last legs. I’m falling asleep. — Я не чувствую ног от усталости. Я засыпаю.

    Выражения to be fast asleep, to be sound asleep и to be deeply asleep переводятся как «крепко спать».

    Look at the kids. They are finally sound asleep. — Посмотри на детей. Наконец-то они крепко спят.

    To be half asleep — быть полусонным.

    Joe is yawning and rubbing his eyes, he might be half asleep. — Джо зевает и трет глаза, должно быть, он полусонный.

    В неформальном английском есть множество фразовых глаголов, при помощи которых можно сказать о процессе засыпания, например to crash out.

    Yesterday I crashed out in a bus and overslept my stop. — Вчера я вырубился в автобусе и проспал свою остановку.

    При этом глагол to crash без предлога может переводиться как «переночевать у кого-то».

    You can crash at my place if it takes you too long to go home. — Можешь переночевать у меня, если тебе очень долго добираться до дома.

    Существует множество других синонимичных фразовых глаголов, которые обозначают «засыпать»: to nod off, to drift off, to doze off и to drop off.

    My granny usually drifts off in front of the telly. — Бабушка обычно засыпает перед телевизором.

    Глаголы to drowse, to nap (to take a nap) и to snooze обозначают «дремать», «спать непродолжительное время».

    Exhausted by the workout she starting drowsing. — Измученная тренировкой, она начала дремать.

    3. To wake up и to get up, to wake и to awake

    Давайте разберемся, в чем разница между wake up и get up. Wake up — просыпаться; будить кого-то, а get up — вставать, подниматься после сна.

    Even the loudest alarm clock won’t wake him up. — Даже самый громкий будильник его не разбудит.
    I merely can’t wake up without a big cup of coffee. — Я просто не могу проснуться без большой чашки кофе.
    She doesn’t normally get up early. — Она обычно не встает рано.

    Wake up также используют в метафорическом смысле — пробудить, привлечь внимание.

    Not only rebellious actions can wake people up and make them see the injustice around. — Не только бунтарские действия могут пробудить людей и заставить увидеть несправедливость вокруг.

    Теперь разберем разницу между глаголами wake и awake. Они оба похожи по значению на глагол wake up — просыпаться, при этом awake — более литературное слово.

    Jane woke to a sudden phone ring. — Джейн проснулась от внезапного телефонного звонка.
    Her grace awoke at 12 a.m. — Ее высочество проснулась в 12 часов.

    С наречием awake есть много полезных выражений, которые вы можете встретить:

    Словосочетание Перевод
    to lie awake лежать без сна
    to be wide awake полностью проснуться
    to be hardly awake, to be barely awake едва проснуться
    to stay awake, to keep awake, to remain awake бодрствовать
    to keep smb awake не давать кому-то спать
    to shake smb awake разбудить кого-то, растолкать

    Вы теперь знаете, как объяснить по-английски, что вы хотите поспать подольше или вас мучает бессонница. Надеемся, вы разобрались в разнице между wake up и get up, wake и awake, fall asleep, nap и crash out и сможете пройти тест.

    Магические функции __sleep и __wakeup

    Имена методов __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state() and __clone() зарезервированы для «магических» методов в PHP. Не стоит называть свои методы этими именами, если вы не хотите использовать их «магическую» функциональность.


    PHP оставляет за собой право все методы, начинающиеся с __, считать «магическими». Не рекомендуется использовать имена методов с __ в PHP, если вы не желаете использовать соответствующий «магический» функционал.

    __sleep() и __wakeup()

    Функция serialize() проверяет, присутствует ли в вашем классе метод с «магическим» именем __sleep(). Если это так, то этот метод выполняется прежде любой операции сериализации. Он может очистить объект и предполагается, что будет возвращен массив с именами всех переменных объекта, который должен быть сериализован. Если метод ничего не возвращает кроме NULL , то это значит, что объект сериализован и выдается предупреждение E_NOTICE .

    Недопустимо возвращать в __sleep() имена приватных свойств объекта в родительский класс. Это приведет к предупреждению E_NOTICE . Вместо этого вы можете использовать интерфейс Serializable.

    Рекомендованное использование __sleep() состоит в завершении работы над данными, ждущими обработки или других подобных задач очистки. Кроме того, этот метод можно выполнять в тех случаях, когда нет необходимости сохранять полностью очень большие объекты.

    С другой стороны, функция unserialize() проверяет наличие метода с «магическим» именем __wakeup(). Если такой имеется, то он может воссоздать все ресурсы объекта, принадлежавшие ему.

    Обычно __wakeup() используется для восстановления любых соединений с базой данных, которые могли быть потеряны во время операции сериализации и выполнения других операций повторной инициализации.

    Пример #1 Sleep и wakeup

    class Connection
    <
    protected $link ;
    private $server , $username , $password , $db ;

    public function __construct ( $server , $username , $password , $db )
    <
    $this -> server = $server ;
    $this -> username = $username ;
    $this -> password = $password ;
    $this -> db = $db ;
    $this -> connect ();
    >

    private function connect ()
    <
    $this -> link = mysql_connect ( $this -> server , $this -> username , $this -> password );
    mysql_select_db ( $this -> db , $this -> link );
    >

    public function __sleep ()
    <
    return array( ‘server’ , ‘username’ , ‘password’ , ‘db’ );
    >

    public function __wakeup ()
    <
    $this -> connect ();
    >
    >
    ?>

    __toString()

    Метод __toString() позволяет классу решать самостоятельно, как он должен реагировать при преобразовании в строку. Например, что напечатает echo $obj;. Этот метод должен возвращать строку, иначе выдастся неисправимая ошибка E_RECOVERABLE_ERROR .

    Нельзя бросить исключение из метода __toString(). Попытка это сделать закончится фатальной ошибкой.

    Пример #2 Простой пример

    // Объявление простого класса
    class TestClass
    <
    public $foo ;

    public function __construct ( $foo )
    <
    $this -> foo = $foo ;
    >

    public function __toString ()
    <
    return $this -> foo ;
    >
    >

    $class = new TestClass ( ‘Привет’ );
    echo $class ;
    ?>

    Результат выполнения данного примера:

    Ранее, до PHP 5.2.0, метод __toString() вызывался только непосредственно в сочетании с функциями echo или print . Начиная с PHP 5.2.0, он вызывается в любом строчном контексте (например, в printf() с модификатором %s), но не в контекстах других типов (например, с %d модификатором). Начиная с PHP 5.2.0, преобразование объекта в строку при отсутствии метода __toString() вызывает ошибку E_RECOVERABLE_ERROR .

    __invoke()

    Метод __invoke() вызывается, когда скрипт пытается выполнить объект как функцию.

    Данный метод доступен начиная с PHP 5.3.0.

    Пример #3 Использование __invoke()

    PHP и волшебные методы: сериализация PHP-объектов глазами хакера

    Содержание статьи

    На повестке дня очень интересная тема — разбор презентации Стефана «Shocking
    News in PHP Exploitation», которую он представил на всеобщее обозрение во время
    конференции PoC2009 в Сеуле 5 ноября. Сразу спешу сообщить, что данное
    исследование в большей степени направлено на будущее, так как на данный момент
    очень немногие программисты стремятся воспользоваться всеми преимуществами
    «волшебных методов» PHP, хотя многие векторы описываемой атаки уже сейчас
    присущи таким великолепным вещам, как WordPress и Zend Framework.

    Краткий ликбез


    Для начала тебе стоит уяснить, что же это за «волшебные методы», для чего они
    нужны и в каких случаях применяются.

    Magic Methods — это, в дословном переводе, Магические Методы, которые
    зарезервированы в php и всегда начинаются с двойного подчеркивания «__»
    (создателями php не рекомендуется называть свои собственные методы, начиная с
    этого самого «__», если ты хочешь использовать некоторую волшебную
    функциональность).

    Вот список таких методов:

    __construct
    __destruct
    __call
    __callStatic
    __get
    __set
    __isset
    __unset
    __sleep
    __wakeup
    __toString
    __set_state
    __clone
    __invoke

    Теперь немного подробнее о каждом методе.

    1. «__construct» и «__destruct» — самые популярные методы, которые реализуют
      базовые понятия объектно-ориентированного программирования: конструктор и
      деструктор;
    2. «__call», «__callStatic», «__get» и «__set» — методы, связанные с
      перегрузкой обращений как к свойствам, так и к методам. Методы «__get()» и
      «__set()» вызываются при установке и получении значения свойства, а методы
      «__call()» и «__callStatic» — при вызове метода. Стоит заметить, что эти
      магические функции будут вызываться только и исключительно в том случае, если
      запрошенные метод или свойство не существуют;
    3. «__isset» — метод, срабатывающий при вызове функций empty() или isset() на
      несуществующем или недоступном свойстве класса;
    4. «__unset» — срабатывает при вызове функции unset() на несуществующем или
      недоступном свойстве класса;
    5. «__sleep» и «__wakeup» — методы, которые вызываются только из функций
      serialize и unserialize соответственно. Метод «__sleep» будет вызван сразу при
      применении к объекту функции serialize, а метод «__wakeup» — при применении
      unserialize. В настоящий момент методы применяются для сохранения текущего
      состояния системы с последующим восстановлением данного состояния (например,
      коннект к базе);
    6. «__toString» — метод, с помощью которого можно обращаться к классу как к
      строке (например, с помощью print или echo);
    7. «__set_state» — метод, который вызывается для классов, экспортирующих
      значения свойств функцией var_export();
    8. «__clone» — вызывается при клонировании объекта (введен для использования
      из-за того, что объекты в php5 и выше передаются по ссылке);
    9. «__invoke» — вызывается при попытке использовать объект в качестве
      функции.

    В рамках статьи нас интересуют 3 описанных метода: «__destruct», «__wakeup» и
    «__toString» — именно они могут вызываться при автозагрузке объектов из функции
    unserialize.

    Многострадальный unserialize

    Немного отступимся от основной темы и рассмотрим некоторые особенности и
    варианты эксплуатации функции unserialize(), которые отметил сам Эссер.

    1. Пример от Стефана, в котором наглядно описаны все поддерживаемые функцией
    типы данных:

    Здесь в сериализованной строке содержатся следующие данные:

    b:1; //boolean
    i:5; //integer
    s:5:»ABCDE»; //string
    a:3: <. >//array
    O:9:»TestClass»:1: <. >//object

    В примере ты можешь заметить, возможно, неизвестные тебе форматы записи
    переменных: «\0*\0pro1» и «\0TestClass\0pro2». «Что это за нулл-байты в именах
    переменных?» — спросишь ты. Заходим на

    www.php.net/manual/en/function.serialize.php и читаем плашку с «Note»:

    Object’s private members have the class name prepended to the member name;
    protected members have a ‘*’ prepended to the member name. These prepended
    values have null bytes on either side.

    Это нехитрое пояснение означает, что при сериализации объектов закрытые члены
    класса должны предваряться именем класса, обрамленным нулл-байтами, а защищенные
    объекты должны начинаться с «\0*\0».

    Также, поясню, что в php5 существуют 3 дескриптора для осуществления контроля
    над доступом к переменным и методам:

    • public (открытый): метод или переменная доступны из любого места в коде;
    • private (закрытый): закрытые методы или переменные доступны только внутри
      класса;
    • protected (защищенный): защищенные методы или переменные доступны только
      внутри класса, где они были объявлены, а также из его производных классов.

    Данные особенности сериализации объектов означают, что при десериализации мы
    можем перезаписать даже защищенные переменные внутри вызываемого класса!

    2. Далее Эссер приводит пример легкой DoS-атаки с помощью описываемой
    функции:

    3. И, наконец, известная тебе по древнему phpBB2 уязвимость с использованием
    == вместо === при сравнении строк и типов данных, проявляющая себе через функцию
    unserialize.

    Здесь имя пользователя и пароль устанавливаются в булево true, а затем скрипт
    пускает нас в админку :).

    Хитрые классы

    Настало время вернуться к нашим баранам.

    Итак, представь, что у нас имеется некая CMS, в которой существует некий
    класс, где присутствует метод __destruct (__wakeup и __toString мы рассмотрим
    немного позже и менее подробно, так как они пока что очень редки в реальной
    жизни, хотя все описываемое в полной мере может относиться и к ним).

    Вот исходник этого класса:

    Использоваться данный класс может, например, так:

    log_dump = time();
    unset($test);
    ?>

    В данном примере сначала вызывается класс testClass, затем переменной
    $log_dump устанавливается значение текущего времени, и вызванный объект
    уничтожается.

    Рассмотрим, что в это время происходит с самим объектом:


    1. Инициализируется класс (если бы существовал магический метод __construct,
      вызывался бы именно он);
    2. Устанавливаются защищенная и закрытая переменные $log_file и $path, в
      которых содержатся имя файла логов и путь к нему;
    3. Устанавливается внешняя переменная $log_dump — то, что мы будем записывать
      в лог-файл;
    4. Вызывается деструктор класса __destruct, во время чего в наш лог-файл
      log.txt записывается текущее время.

    Как видишь, у нас получился неплохой пример логгера :).

    Эксплуатируй это!

    Теперь настало время представить, что описанный выше класс уже включен в код
    нашей CMS и что вызываемые из базы данных поля профиля пользователя (или любые
    другие поля) проверяются на сериализацию. В качестве примера подойдут функции из
    уже известного тебе WordPress’а:

    Здесь видно, что, будучи примененной к какой-либо строке, при определенных
    условиях функция maybe_unserialize() может пропустить оную через нужную нам
    unserialize().

    Рассмотрим подробнее наш класс testClass в контексте сериализации:

    1. Переменная $log_file является защищенной, следовательно, при сериализации
      она должна выглядеть как «\0*\0log_file»;
    2. Переменная $path является закрытой и при сериализации выглядит как
      «\0testClass\0path» (префикс — имя класса);
    3. Последняя переменная $log_dump является открытой всюду и для всех, так что
      никаких специальных манипуляций с ней проводить не нужно.

    Из данных утверждений вытекает возможный эксплойт:

    В примере наш объект вызывается с предустановленными переменными $log_file =
    «evil.php\0»; (нулл-байт нужен для обрезания предустановленного в классе
    расширения .txt) и $log_dump = » «;. После десериализации, а
    следовательно, и уничтожения объекта в директории с логами должен появиться файл
    evil.php, содержащий наш злонамеренный код :).

    В случае с __wakeup вся эксплуатация выглядит совершенно таким же образом
    (потому что этот метод также вызывается при десериализации), а вот в случае с
    __toString уязвимый код в CMS должен выглядеть чуть-чуть иначе:

    Здесь десериализованная строка должна сразу же выводиться на экран с помощью
    print или echo, — тогда и только тогда будет вызван указанный метод.

    Для более глубокого понимания описанного класса уязвимостей советую
    внимательно изучить презентации Стефана Эссера (ссылки, как всегда, ищи в
    сносках). В них содержатся реальные примеры использования метода __destruct в
    Zend Framework с выполнением кода через preg_replace, инклудом удаленных файлов,
    загрузкой и удалением произвольных файлов и т.д.

    Memento

    Описанное выше является лишь документированными возможностями нашего любимого
    PHP, просто существуют специалисты, которые изучают эти возможности немного
    глубже, чем обычные кодеры :). Так что, рекомендую с огромной осторожностью
    применять в своих проектах магические методы __wakeup, __toString и __destruct
    вкупе с десериализацией любого пользовательского ввода (вообще, никогда не стоит
    доверять пользователям). Я же с нетерпением буду ждать новых исследований от
    Стефана Эссера, чего и тебе советую!

    Магические функции __sleep и __wakeup

    Имена функций __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() и __debugInfo() являются магическими в PHP. Не стоит называть свои методы этими именами, если вы не хотите использовать их магическую функциональность.

    PHP оставляет за собой право все методы, начинающиеся с __, считать магическими. Не рекомендуется использовать имена методов с __ в PHP, если вы не желаете использовать соответствующую магическую функциональность.

    __sleep() и __wakeup()

    Функция serialize() проверяет, присутствует ли в вашем классе метод с магическим именем __sleep(). Если это так, то этот метод выполняется до любой операции сериализации. Он может очистить объект и должен возвращать массив с именами всех переменных этого объекта, которые должны быть сериализованы. Если метод ничего не возвращает, то сериализуется NULL и выдается предупреждение E_NOTICE .

    Недопустимо возвращать в __sleep() имена закрытых свойств в родительском классе. Это приведет к ошибке уровня E_NOTICE . Вместо этого вы можете использовать интерфейс Serializable.

    Предполагаемое использование __sleep() состоит в завершении работы над данными, ждущими обработки или других подобных задач очистки. Кроме того, этот метод может полезен, когда есть очень большие объекты, которые нет необходимости полностью сохранять.

    С другой стороны, функция unserialize() проверяет наличие метода с магическим именем __wakeup(). Если она имеется, эта функция может восстанавливать любые ресурсы, которые может иметь объект.

    Предполагаемое использование __wakeup() заключается в восстановлении любых соединений с базой данных, которые могли быть потеряны во время операции сериализации и выполнения других операций повторной инициализации.

    Пример #1 Сериализация и десериализация

    class Connection
    <
    protected $link ;
    private $dsn , $username , $password ;

    public function __construct ( $dsn , $username , $password )
    <
    $this -> dsn = $dsn ;
    $this -> username = $username ;
    $this -> password = $password ;
    $this -> connect ();
    >

    private function connect ()
    <
    $this -> link = new PDO ( $this -> dsn , $this -> username , $this -> password );
    >

    public function __sleep ()
    <
    return array( ‘dsn’ , ‘username’ , ‘password’ );
    >

    public function __wakeup ()
    <
    $this -> connect ();
    >
    > ?>

    __toString()

    Метод __toString() позволяет классу решать, как он должен реагировать при преобразовании в строку. Например, что вывести при выполнении echo $obj;. Этот метод должен возвращать строку, иначе произойдёт фатальная ошибка уровня E_RECOVERABLE_ERROR .

    Нельзя выбросить исключение из метода __toString(). Это приведет к фатальной ошибке.

    Пример #2 Простой пример

    // Объявление простого класса
    class TestClass
    <
    public $foo ;

    public function __construct ( $foo )
    <
    $this -> foo = $foo ;
    >

    public function __toString ()
    <
    return $this -> foo ;
    >
    >

    $class = new TestClass ( ‘Привет’ );
    echo $class ;
    ?>

    Результат выполнения данного примера:

    Стоит отметить, что до PHP 5.2.0 метод __toString() вызывался только непосредственно в сочетании с echo или print . Начиная с PHP 5.2.0, он вызывается в любом строчном контексте (например, в printf() с модификатором %s), но не в контексте других типов (например, с %d модификатором). Начиная с PHP 5.2.0, преобразование объекта в строку при отсутствии метода __toString() вызывает ошибку E_RECOVERABLE_ERROR .

    __invoke()

    Метод __invoke() вызывается, когда скрипт пытается выполнить объект как функцию.

    Данный метод доступен начиная с PHP 5.3.0.

    Пример #3 Использование __invoke()

    Илон Маск рекомендует:  Что такое код asp logmoduleid
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL