Intereting Posts
Есть ли способ использовать PHP WebSocket в Heroku ?, кажется, по умолчанию есть только поддержка других технологий php требует вызова класса изнутри метода изменить файл xml через php-форму Как запустить работу cron с помощью zend framework 2 Доктрина 2: Могут ли сущности быть сохранены в сеансах? Я хочу загрузить файл и при загрузке файла значения файла должны быть помещены в мой массив «Существует ошибка» при нажатии на некоторые страницы администрирования Silverstripe PHP-запрос из MySQL без дублирования Неустранимая ошибка: вызов неопределенного метода GuzzleHttp \ Client :: request () с помощью Guzzle 6 Доктрина, пространство имен и объекты автозагрузки PHP по-прежнему не позволяет загружать файлы более 2 МБ PHP: Требуется ли продление класса другому «использовать» для вызова пространства имен? Highchart – отображение данных JSON – MYSQL / PHP Как я могу сделать ссылку на загрузку случайного имени php на странице? PHP: 2 формы различных страниц действий, только 1 действие действия формы

Неявное преобразование типов для классов PHP?

Есть ли способ сказать php complier, что я хочу конкретное неявное преобразование из одного типа в другое?

Простой пример:

class Integer { public $val; } function ExampleFunc(Interger $i){...} ExamFunc(333); // 333 -> Integer object with $val == 333. 

[edit] … кто-то попросил пример. Вот пример из c #. Это логический тип, который меняет значение после его обращения один раз.

  /// <summary> /// A Heisenberg style boolean that changes after it has been read. Defaults to false. /// </summary> public class hbool { private bool value; private bool changed = false; public hbool() { value = false; } public hbool(bool value) { this.value = value; } public static implicit operator bool(hbool item) { return item.Value; } public static implicit operator hbool(bool item) { return new hbool(item); } public bool Value { get { if (!changed) { value = !value; changed = true; return !value; } return value; } } public void TouchValue() { bool value1 = Value; } public static hbool False { get { return new hbool(); } } public static hbool True { get { return new hbool(true); } } } [Test] public void hboolShouldChangeAfterRead() { hbool b = false; Assert.IsFalse(b); Assert.IsTrue(b); Assert.IsTrue(b); hbool b1 = false; Assert.IsFalse(b1); Assert.IsTrue(b1); Assert.IsTrue(b1); hbool b2 = true; Assert.IsTrue(b2); Assert.IsFalse(b2); Assert.IsFalse(b2); bool b3 = new hbool(); Assert.IsFalse(b3); Assert.IsFalse(b3); Assert.IsFalse(b3); } 

Длительный ответ:

Я думаю, что очень сложно (для читателей невозможно ) для PHP сделать неявное преобразование в этом случае.

Помните: тот факт, что вы называете свой класс Integer, является подсказкой для человеческого читателя кода, PHP не понимает, что на самом деле он используется для хранения целого числа. Кроме того, тот факт, что он имеет атрибут, называемый $ val, является подсказкой для читателя, который должен содержать значение целого числа. Снова PHP не понимает ваш код, он только выполняет его.

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

 class Integer { public $val; function __construct($val) { $this->val = $val; } } function ExampleFunc($i){ if (is_numeric($i)) { $iObj = new Integer($i); } ... } ExamFunc(333); // 333 -> Integer object with $val === 333. 

Это не так круто, как вам бы хотелось, но опять же, возможно, что PHP имеет синтаксический сахар, который скроет явное преобразование более или менее.

Укороченная версия:

Так или иначе вам понадобится явное преобразование

PHP5 имеет тип намека, с ограничениями: http://ca2.php.net/manual/en/language.oop5.typehinting.php

Указанные типы должны быть объектами или массивами , поэтому встроенные типы, такие как строка и int , недопустимы.

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

На самом деле это возможно с расширением SPL_Type . Он определяет классы для примитивных типов , объекты которых взаимозаменяемы с примитивными типами PHP (booleans, enums, ints, float и strings).

Первый пример будет работать, просто наследуя от SplIt следующим образом:

 class Integer extends extends \SplInt{} function ExampleFunc(Interger $i){...} ExamFunc(333); // 333 -> Integer object with $val == 333. 

Проблема заключается в том, что код расширения Spltypes не поддерживается с 2012 года, и к моменту этого сообщения он не портирован на PHP 7, и нет такого плана.

ОБНОВЛЕНИЕ Я нашел следующий неофициальный порт типов SPL для PHP 7. Используйте на свой страх и риск: https://github.com/esminis/php_pecl_spl_types

Основные инструкции по установке:

  1. Клонировать код: https://github.com/esminis/php_pecl_spl_types.git
  2. Создайте файл конфигурации . Внутри каталога кода введите: phpize .
  3. Создать файл make: ./configure
  4. Скомпилируйте код и установите: make && make install
  5. Добавьте модуль в свой PHP-конфигуратор. В Ubuntu введите echo "extension=spl_types.so" > /etc/php7/conf.d/spl_types.ini
  6. Перезапустите PHP-FPM (при его использовании): service php7.0-fpm restart

Нет, PHP не является строго типизированным языком.

Вы спрашиваете, как набирать текст? Ты можешь сделать:

 $ php -r 'var_dump("333");' string(3) "333" $ php -r 'var_dump((int)"333");' int(333) 

В противном случае PHP слабо типизирован, так что вообще вам не нужно это делать. Это подразумевается языком. Например. если функция принимает числовой аргумент, то это число может быть строковым, целочисленным или float все равно; При необходимости значение преобразуется. Вот почему вы можете, например, echo 33 без ошибок.

PHP не строго типизирован.

Вы хотите что-то вроде, всякий раз, когда вы передаете экземпляр hbool в функцию, ожидающую bool, она автоматически конвертируется с использованием вашего неявного конвертера.

Что происходит, так это то, что никакая функция «ожидает» bool, все это динамически типизировано. Вы можете принудительно выполнить явное преобразование, вызвав (int)$something но если это так, вы можете передать вместо $something->to_otherthing() вместо неавтоматических преобразований.

PS: Я уверен, что я не понимаю здесь. Я попытаюсь отредактировать этот ответ после того, как я что-нибудь съел 🙂

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

 function a(int $a){...} a(new Integer(1)); 

в настоящее время невозможно. Если вы хотите создать фреймворк, который предлагает вам это и даже больше, посмотрите на BlazeFramework, который имеет такие классы-оболочки.

Операционная перегрузка не работает ни в php. Реализация, возможно, слишком много для написания, но я даю вам подсказку! PHP вызывает набор обратных вызовов с помощью set_error_handler() с уровнем ошибки E_RECOVERABLE_ERROR и debug_backtrace() предоставляет информацию о вызове функции / метода.

Если вы этого не сделаете, посмотрите на реализацию метода blaze\lang\System#systemErrorHandler() , но, возможно, лучше использовать инфраструктуру, если вы хотите больше таких функций.