Intereting Posts
PHP mysqli – возвращает ассоциативный массив из подготовленного оператора PHP: move_uploaded_file () не удалось открыть поток: нет такого файла или каталога проблема с набором символов domdocument Получите данные на стене или стене группы facebook для использования на личном веб-сайте Как установить отключенную опцию выбора в Laravel? PHP Найдите первую часть почтового индекса в Великобритании, когда полный или часть может быть введена Вставить несколько строк из массива, сохраненного в сеансе в таблицу? Как объединить несколько изображений и текст в одно изображение? пакеты переменной длины в php lumen: App \ Http \ Controllers \ Класс контроллера не найден с новой установкой Как Zend DB управляет подключениями к базе данных Предлагаемое решение: создание уникальных идентификаторов в распределенной среде Ошибка QuickBooks API при обновлении Bootstrap 3 Modal с использованием данных набора записей PHP Изменение класса css с использованием переменной php

как создать класс php, который может быть запущен до логического (быть правдивым или ложным)

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

Как создать класс, который может быть запущен в boolean, поэтому класс может быть правдивым или ложным?

Простой тест показывает, что объект пустого класса правдивый:

class boolClass {} $obj = new boolClass(); var_dump( (bool)$obj); //prints //bool(true) 

Но мне нужно решить, действительно ли мой класс правдивый или фальшивый. Есть ли способ сообщить движку PHP, как отличить мой класс от boolean? Как я мог сделать с __toString ()?

Задний план:

Допустим, я пишу класс вроде этого (это только пример):

 class MyCollection implements ArrayAccess, Iterator { //... } 

В настоящее время я активно использую эти шаблоны:

 $var = array(); if (empty($var)) { //array is empty, (or there is no array at all) // I do something here } 

Я бы хотел, чтобы это выглядело так:

 $var = new MyCollection(array()); 

и не оставляйте остальных без изменений. Но $ var, содержащий MyCollection, всегда правдивый, поэтому мне нужно было бы все условия:

 if ($var->isEmpty()) { //... } 

Но это неприемлемо, так как моя кодовая база имеет много мегабайт.

Любое решение здесь?

Solutions Collecting From Web of "как создать класс php, который может быть запущен до логического (быть правдивым или ложным)"

На этой странице перечислены магические методы, которые вы можете определить для ваших классов.

http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring

Вы демонстрируете, что уже знаете о __toString() .

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

После сильной тоски, разочарования и взлома – я считаю, что нашел решение. Решение не требует каких-либо расширений; он может быть реализован с очень небольшим количеством шаблонов PHP. Однако, прежде чем внедрять это решение самостоятельно, обратите внимание, что это – фактически – ОГРОМНЫЙ взлом. Это, как говорится, вот что я обнаружил:

Разочарованный, я потратил некоторое время на просмотр документации PHP для Booleans . В то время как классы, созданные пользователем, просто лишены возможности быть брошенными как логические, один класс – как ни странно – получил возможность. Проницательный читатель заметил бы, что этот класс есть не что иное, как встроенный SimpleXmlElement . По способу дедукции, кажется справедливым предположить, что любой подкласс SimpleXmlElement также наследует его уникальную возможность булевского литья. Хотя теоретически этот подход кажется верным, магия, окружающая SimpleXmlElement, также устраняет полезность этого подхода. Чтобы понять, почему это так, рассмотрим этот пример:

 class Truthy extends SimpleXmlElement { } 

Truthy является подклассом SimpleXmlElement, поэтому мы должны иметь возможность проверить, было ли унаследовано его специальное свойство boolean-casting:

 $true = new Truthy('<true>1</true>'); // XML with content eval's to TRUE if ($true) echo 'boolean casting is happening!'; $false = new Truthy('<false></false>'); // empty XML eval's to FALSE if (!$false) echo 'this is totally useful!'; 

Действительно, свойство boolean-casting, предоставленное SimpleXmlElement, наследуется Truthy. Однако этот синтаксис неуклюж, и маловероятно, что из этого класса вы получите много полезности (по крайней мере, по сравнению с использованием SimpleXmlElement изначально). В этом сценарии возникают проблемы:

 $false = new Truthy('<false></false>'); // empty XML eval's to FALSE $false->reason = 'because I said so'; // some extra info to explain why it's false if (!$false) echo 'why is this not false anymore?!?'; else echo 'because SimpleXMLElements are magical!'; 

Как вы можете видеть, попытка установить свойство в нашем подклассе сразу же разрывает утилиту, которую мы получаем из унаследованного boolean-casting. К сожалению для нас, SimpleXmlElement имеет еще одну магическую особенность, которая нарушает наше соглашение. По-видимому, когда вы устанавливаете свойство SimpleXmlElement, оно модифицирует XML! Посмотреть на себя:

 $xml = new SimpleXmlElement('<element></element>'); xml->test = 'content'; echo $xml->asXML(); // <element><test>content</test></element> 

Ну, есть какая-нибудь утилита, которую мы могли бы получить из подкласса SimpleXmlElement! К счастью, после большого взлома, я нашел способ сохранить информацию в этом подклассе, не нарушая логическую магию кастинга: комментарии!

 $false = new Truthy('<!-- hello world! --><false></false>'); if (!$false) echo 'Great Scott! It worked!'; 

Прогресс! Нам удалось получить полезную информацию в этом классе, не нарушая при этом булевское кастинг! Хорошо, теперь все, что нам нужно сделать, это очистить его, вот моя окончательная реализация:

 class Truthy extends SimpleXMLElement { public function data() { preg_match("#<!\-\-(.+?)\-\->#", $this->asXML(), $matches); if (!$matches) return null; return unserialize(html_entity_decode($matches[1])); } public static function create($boolean, Serializable $data = null) { $xml = '<!--' . htmlentities(serialize($data)) . "-->"; $xml .= $boolean ? '<truthy>1</truthy>' : '<truthy/>'; return new Truthy($xml); } } 

Чтобы удалить некоторые неуклюжие, я добавил публичный статический заводский метод. Теперь мы можем создать объект Truthy, не беспокоясь о деталях реализации. Фабрика позволяет вызывающему определить произвольный набор данных, а также булевское литье. Затем метод данных может быть вызван для получения копии этих данных только для чтения:

 $false = Truthy::create(false, array('reason' => 'because I said so!')); if (!$false) { $data = $false->data(); echo 'The reason this was false was ' . $data['reason']; } 

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

Вы можете взглянуть на расширение оператора PHP, которое вы можете использовать для перегрузки многих операторов, включая == и ===. С этим расширением теоретически вы можете написать класс, сопоставимый с булевыми значениями, например:

 if($object == true) 

Ты не можешь.

В PHP объект, когда cast to bool всегда производит true . Невозможно изменить это.

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

OTOH, почему размер кода является большой проблемой? Попытайтесь минимизировать код, который вы включаете каждый раз при запуске php. Блуждающий код, который не используется, не имеет значения. Если вам нужно включить много кода, попробуйте использовать программное обеспечение для кеширования, такое как MMCache.

И чтобы ответить на ваш первоначальный вопрос, AFAIK не существует способа добавить принуждение типа к классам PHP. экземпляр всегда будет оценивать значение true.

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

 class foo { public function __toString() { return strval(false); } } $foo = new foo(); if (strval($foo) == false) // non-strict comparison { echo '$foo is falsy'; } echo (bool) strval($foo); // false