Как стать автором
Обновить

Комментарии 98

А что это изменит?

Лучше бы нормальную модульность сделали, так чтобы можно было разделять на выполняемые скрипты и скрипты-модули, которые можно только подлючать + приватные классы и функции (имена которых доступны только в пределах модуля), типа как статические функции в С.
Мне кажется нужно исходить из реалий. Чтобы реализовать то что Вы хотите, потребуется не мало времени и переписи кода. PHP8 может и будет содержать такую функциональность, если разработчики сочтут ее нужной. :-)
Мне что когда появляются такие потребности имеет смысл посмотреть на другие языки, где это уже давно и естественно имеется.
Согласен
Лично я не отказался бы от строгой типизации, ибо лично меня напрягает то, что я не могу быть точно в уверен в том, что переменная будут иметь именно тот тип, который я хочу.
(int)$yourVar
?
да ты что))
а кто мне гарантирует что $yourVar может быть корректно приведен к типу инт?
и как на счет передачи параметров в ф-ю да и хотелось бы, что бы вся эта проверка выполнялась на этапе анализа кода а не на этапе выполнения))
И в чём проблема? Напишите хоть на этапе подключения библиотек, кто мешает?
Любой тип корректно приводится к типу int.
За что минусуете?!
В PHP ЛЮБОЙ тип совершенно корректно приводится к ЛЮБОМУ.
а int к array?
нормально приводит
$a = 5;
$a = (array)$a; // => array( 0 => 5 );
array to string?
array to string = serialize
Если вам не нравится сериализация, можно использовать implode
Вот от этого и возникают глючные и дырявые php-скрипты. Если точно не знаешь какой у тебя тип и к чему его можно корректно привести, как его вообще можно использовать??
вы явно путаете ПХП с чем-то! тот факт что на пхп намного легче писать глючные и дырявые скрипты исходит из самой сти языка и нечего с этим спорить! если есть желание сделать их пхп джаву или си-шарп - проще просто перейти на один из них
не хочу (int), хочу (CustomClass) !!!
тогда нужен какойто magic method вроде: __get_state
Вот это и следует предложить авторам РНР в соседнем топике
на самом деле такое желание продиктовано в первую очередь ленью. мне лень помнить и набрать руками методы, я хочу автокомплит в IDE. но бывает так, что IDE не может определить тип переменной (например $c = unserialize($str);) и хочется иметь возможность подсказывать ей :)

насколько подобные подсказки могут быть полезны во время исполнения кода я пока не думал, но вдруг и там они окажутся полезными? ;)

magic method вроде: __get_state


не... не нужен мне метод... что он будет возвращать ?!
сейчас Zend Studio автокомплитит опираясь на указанные в phpdoc данные, а тут она на что будет ориентироваться?!

к тому-же для удобства разработки я могу и сам нагородить кучку снабженных соответсвующими phpdoc комментариями методов, типа cast2CustomClass который будет тупо возвращать переданный ему параметр. но это сказывается на производительности, в итоге перед релизом эти "обертки" приходится удалять...

в C# и ActionScript2(3) есть еще один оператор для кастинга — «AS».

(obj as CustomClass).CustomClassMethod() примерно* эквивалентно ((CustomClass)obj).CustomClassMethod()

VS IntelliSence(Resharper), Flex Builder и FDT (про FB и FDT могу ошибаться, давно в руках не держал) понимают что происходит, убирают ворнинги и дают нормальные подсказки.



почему бы в PHP не добавить подобный?!...
я понимаю что (int) это не кастинг а приведение и использование такого же синтаксиса для кастинга поробит кучу головняка, но мне бы хватило и $c = ($obj as CastomClass), лишь бы IDE нормально потом автокомплит предлагало...


---
* примерно потому что в AS2(3) кастинг через as работает немного по другому чем через ()
as уже занять для foreach
насчет лени согласен полностью, в продуманом коде кастинг сложных обьектов не нужен, и просто усложнит чтение и поддержку кода.
так что кастинг это скорее фишка ради фишки (:
as уже занять для foreach

OMFG!!!
постоянно пользуюсь, и при этом совсем о нем забыл! :")

хотя, на счет занятости под foreach можно поспорить... с технологической точки зрения AS может работать по разному в зависимости от контекста. для парсера это не есть большая проблема. другое дело что неоднозначность оператора породит смуту с мозгах начинающего девелопера... :(



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

в корне не согласен. кастинг в качестве подсказки при чтении ничем не хуже комментария тпа:
//а щаз мы распакуем наш экземпляр CustomClass и будем с ним работать
$c = unserialize($str);

а вот при поддержке/разработке, в отличие от комментария, он отлично помогает IDE ориентироваться в свойствах/методах распакованного инстанса ;)

в принципе, меня бы даже устроило если бы я мог в коде к любой переменной при объявлении дописать phpdoc (как при объявлении свойств класса). вроде такого:

/**
* @var CustomClass
*/
$c = unserialize($str);

но к сожалению IDE (ZendStudio) такого внутри function не понимают :( а заставить разработчиков IDE сделать подобное гораздо проще протолкнув идею кастинга в язык, чем объяснять непосредственно разрабам IDE что это полезная фича...

З.Ы.: имхо, единственные кто разрабатывают отличную IDE и при этом обращают внимание на своих потребителей это JetBrains (IDEA), все остальные настолько инертны, что заходить к ним нужно «через огород» %(
ну как это не понимают? именно зенд студия как раз и понимает! просто немного другой синтаксис (чтото вроде /* @var $asd Class */). Читать "советы дня" иногда бывает полезно (кстати вспоминая ИДЕю - какие молодцы ребята из JetBrains что показывают эти советы в самое подходящее время - во время выполнения длительных операций, когда все равно больше делать нечего)
ну как это не понимают? именно зенд студия как раз и понимает! просто немного другой синтаксис (чтото вроде /* @var $asd Class */)


для локальных переменных не работает, только для полей класса.
//Zend Sudio for Eclipse 20080107
другое дело что неоднозначность оператора породит смуту с мозгах начинающего девелопера...

Проблемы негров шерифа не волнуют.
что IDE не может определить тип переменной

/* @var .... */ - комментарии лишними никогда не будут
такой комментарий рулит только для полей класса. для локальных переменных он может помочь читающему, но не IDE :(
ну знаете ли. погуглите, почитайте типс оф зе дей, попробуйте. специально не поленился и проверил - я даже в синтаксисе не ошибся, отлично работает для локальных переменных в ZS 5.5 и в ZS Neon (Build ID: 20071129). вряли в 20080107 эту возможность убрали, да?
перед тем как написать специально проверял.
для полей класса работает, для локальной переменной объявленной внутри метода — нет.

вы уверены что в совем эксперименте присваиваете object?

у ва свот так работет !?
/* @var $c CustomClass */
$c = unserialize($ddd);
$c->...и тут сработал авоткомплит !?

у меня — нет :(
попробуйте поменять первые две строки местами. а вообще - да, работает. если хотите покажу скрин
попробуйте поменять первые две строки местами.

огромное человеческое спасибо!
так оно действительно работает.
Если лень - можно юзать Ruby On Rails. Замечательный фреймворк
потакание лень иногда ограничивается требованиями ;)
может сменить язык?)
и как на счет передачи параметров в ф-ю да и хотелось бы, что бы вся эта проверка выполнялась на этапе анализа кода а не на этапе выполнения))
ну так и пишите на шарпе или на джаве :)
Ни разу не было необходимости в строгой типизации, если что, то можно приводить типы вручную
В 85% случаев хватает тап-хинтинга для объектов и массивов, в 5% не хватает для булевого типа данных.
В оставшихся 10% он ИМХО не нужен.
В некоторых случая было бы удобно обозначить тип и больше не задумываться об этом. Только надо аккуратно использовать.
Впрочем, никто и не заставляет использовать. А так, в целом, сократило бы каскадные приведения типов на разных уровнях.
В PHP5 ввели type hinting для классов.

И сразу же стало ясно, что это довольно-таки бесполезно.

Например: на сайте есть функция поиска пользователей, где можно указать, каким городом ограничить поиск, — а можно искать во всех городах.

Я объявляю public static function search(City $city) в классе User.

И тут же возникает проблема.

Я хочу обозначить отсутствие города (то есть то, что надо искать во всех городах) значением NULL.

Но при попытке вызвать User::search(NULL) я получаю ошибку, потому что значение NULL относится к типу null, а не object (и уже тем более не City).

И я иду и удаляю type hint.
да, это вообще какая-то непонятная ситуация с нуллами, ни на какие яхыки ен похожая. при такой постановке полезность тайп хинтинга действительно падает на порядок. а ведь можно сделать чтото похожее на дотнет (по синтаксису): City не принимает нулл, City? - принимает
*языки не...
пора спать
я вот пробую в 5.2.5 передать null в функцию с типизированным парамером и ошибок не выдаёт. может надо обновить вашу версию?
print PHP_VERSION; User::search(NULL));


5.2.5

Catchable fatal error: Argument 1 passed to User::search() must be an instance of City, null given
У меня такой код корректно работает
class A
{
public $var = 5;
}

class User
{
public static function callme(A $arg0, A $arg1)
{
print_r($arg0);
print_r($arg1);
}
}


$a = new A();

User::callme($a, NULL);
У меня ваш код показывает Catchable fatal error: Argument 2 passed to User::callme() must be an instance of A, null given .

Может быть, print error_reporting();?
стоит стандартно по-девелоперски: E_ALL | E_RECOVERABLE_ERROR | E_STRICT == 8191
но я понял в чём дело и почему у меня нет ошибки. я использовал свой sandbox в котором eval($code); и который нормально отреагировал на null вместо объекта.
но если указать function callme(A $arg0, A $arg1=null)) то
User::callme($a, NULL); работает корректно
+1 :)
не знал, спасибо!
объявите ф-ию как public static function search(City $city = null)
Да, действительно, «default value for parameters with a class type hint can only be NULL», но что, если я не хочу делать его дефолтовым?

Или немного другая постановка вопроса: я могу передать функции объект класса City, чтобы искать в этом городе, или FALSE, чтобы искать в городе по умолчанию, или NULL, чтобы искать во всех городах. Как сделать?
Мне кажется, разумнее эту логику включать именно в сам класс City и функцию search: то есть определить внутри City isNull() и isDefault(), а в search уже искать в зависимости от возвращаемых значений этих проверок.
Чем же это разумнее?
Тем, что город по умолчанию - это тоже город. И пустой город - это тоже город (ложка, которой нет). А функция search уже должна свою работу координировать с тем, какого "типа" этот город.

Имхо вся соль тайп-хинтинга как раз в этом.
Если глянуть на тот же сишарп, который имхо вполне религиозно корректен, то там такой бяки нет.
И это вполне логично: мы ведь передаём функции ссылку на объект. И эта ссылка вполне имеет право быть пустой. Естественно, при попытке обратится из метода к членам класса вылезет эксепшн. Но отловить его, или, тупо сравнить полученную ссылку с нуллом никто не мешал.

Другое дело, что ваше рассуждение вполне верно. Если что-то может быть нулём, то метод можно перегрузить (а в случае с пыхпыхом — задать умолчание параметру). Однако, если я правда хочу другой дефолт?
другой дефолт это new City('Kiev')? наверное все таки ничего хорошего в этом нету. но остается вопрос - а если я не хочу дефолта?
а чего вы хотите? синтаксиса вроде fucntion func(City or bool or null $a)??? если вы хотите именно такую логику - проверяйте тип пришедшей переменной уже в самой функции. но как уже сказали - ничего хорошего в такой логике нету. если потом кому-то надо будет разобратся во всех Ваших вариантах входящих данных - он вспомнит Вас "незлым тихим словом"
если очень-очень сильно хочется, то можно извратиться:
if ( !check_type($arg, TYPE_INT|TYPE_FLOAT) )
    return false;

вместо многострочных условий
но как вы сами понимаете, это требует ещё определённых дополнений, чтобы программист мог узнать, что же произошло, почему вернулся false. В таком случае прийдётся: return gen_error(false,E_BAD_PARAM_TYPE,$arg);
Вас это пугает? Да, так и должно быть, хотя я бы предпочел throw new ArgumentException("something could not be something");
это вариации на тему. тут вопрос в излишках кода. мне, как програмеру пришедшему из плюсов, дублировать каждый раз строчки кода, которые мог бы реализовывать сам интерпретатор, видится излишним. ну и потом полагаться, что программист не забудет где-то вставить, не отложит, проверку типа параметра кажется слишком большим пренебрежением в багоустойчивости.
т.е. вы как программер пришедший из плюсов привыкли там иметь функции с аргументами вида (int or bool or someclass a)? а вот мне лень каждый раз дублировать код связанный с ОРМ (пусть даже генерится генератором, все равно дублирование), а давайте придумаем синтаксис и встроим ОРМ в интерпретатор. можно предлагать еще варианты.
не дублируйте. кто-то запрещает? этого никто не отберёт и не собирается этого делать.
видимо Вы меня не поняли. Я просто выразил свое скептическое отношение к тому, что стоит в синтаксис добавлять возможности, необходимости в которых нет, а полезность - сомнительна.
полезность состоит в перенесении достаточно большой части кода (по крайней мере, у меня почти в каждой функции есть проверка на тип аргумента при 2-3 строчках самой функции. выгядит некрасиво) на интерпретатор.
перенос орма в интерпретатор тоже позволит сэкономить немерянное количество кода!
необходимый ORM можно вынести не в интерпретатор, а в отдельный подключаемый модуль, что более целесообразно, дабы не перегружать интерпретатор.
как у Вас на все есть ответ. ну вот лень мне сейчас придумывать пример не такой обьемный как орм, чтоб Вы не могли сказать про модуль. думаю что можно много чего придумать и добавить в интерпретатор как бы небольшого, как бы полезного. но вот что будет если ВСЕ эти вещи взять и добавить?
кстати а вот и пример вспомнился. как бы вы отнеслись к аналогу LinQ в пхп?
мы говорим о разных вещах. ORM не является частью функционала языка PHP. Вы бы ещё предложили включить XPath и SQL в PHP интерпретатор. это абсурдно.
типизация - это атомарная вещь, а то что вы предлагаете - достойно функционала целого модуля.
ну я же уже согласился с Вами по поводу ОРМ. кстати о Sql - LinQ как раз и является включением почти Sql в синтаксис языка :) . И я как раз предлагаю этого не делать. Я повторю еще раз. Можно придумать много небольших полезных вещей, которые бы в каких-то местах уменьшили количество кода. Действительно ли стоит ВСЕ их включать в язык? Я понимаю и согласен с полезностью type hintinga для простых типов. Но то, что предлагаете Вы - мне непонятно. Вы ведь все равно будете делать в методе ветвление, для того чтобы проверить что Вам дали - сити, фолс и нул. разве трудно вконце написать else throw ....? Это больше чем (City or bool or null $a)?
При приёме класса City возможен либо экземпляр класса, либо null - остаётся лишь одна проверка, либо без таковой, если параметр передаётся дальше. При приёме атомарного класса int, string - вобще никаких проверок делать не надо, так как принять null в этом случае невозможно. Откуда вы взяли, что bool может быть идентичен null или City. Boolean - это такой же атомарный класс как и int.

Если честно, я не понимаю ваш пример func(City or bool or null $a). Он некоректный. Город не может отвечать на вопрос "да" или "нет".
хм. а может вообще стоило прочитать на что я отвечал, когда принялись критиковать мое сообщение? да и говорить что Вы не поняли что я говорил в самом начале, после того как мы написали комментариев по 10 как-то странно...
сперва не обратил должного внимания на то, что заметил вконце.
опять 25 - ПХП язык априори такой, что подразумевает немеряно мест где программист может сделать ошибку. если все эти места убрать - получится одно из двух: либо спп либо ява. или смиритесь с тем что ПХП таков или выберите себе другой язык!
подождите, в PHP никто не собирается отбирать безтиповую передачу параметров. предлагается наоборот, добавить, наряду с бестиповой передачей ещё и типовую. Это нормальное развитие языка для нужд его использующих.
точнее, расширение уже существующей типизиции параметров.
Для таких случаев требуется введение нулевого объекта.
class CityNull extends City {
public function isNull() {
return true;
}
}
А кто вам мешает сделать public static function search(City $city = null) и не вызывать метод search с параметрами, когда надо передать null?
Мешает то, что я хочу указать второй параметр (скажем, имя), который значения по умолчанию иметь не будет.

Сразу скажу, что поменять параметры местами нельзя.
static function search(City $city = null)
было бы неплохо строго типизировать параметры функций, так как приходится делать лишние проверки типа
if ( !is_int($argument0) )
return false;
плохая проверка ... строки цифр не пройдет её. (а такие строки встречаются повсюду: $_GET, из БД, результаты рег.выражений, ...)
проверка $_GET, из БД - это другие частные случаи и я не говорил о них. Если хотите пример,тов разных функциях ядра CMS, где, например, принимается seed, который должен быть только int. Тогда приходится делать такие вот проверки.
хотя в PHP правильно сделано, что нет точной типизации, так как в каждый момент работы скрипта программист не может точно знать, что прийдёт именно значение требуемого типа. А в PHP это вызывает fatal error, что привело бы в самый неподходящий момент к сбою сайта. Ну и доставило бы большую кучу головной боли.
это дурацкий комент :)
НЛО прилетело и опубликовало эту надпись здесь
мне хватает type hinting только для обьектов и массивов
с простыми типами считаю создаст лишние грабли.
хотя от простого деление на чтото вроде: numeric и string сложно отказатся, без уточнений bool,float,int (:
даешь нормальный кастинг и хинтинг!

а то "Traditional type hinting with int and string isn't supported."... куда это годится !?
и кастинга нема нормального... :(

и еще бы overloading на основе хинтинга (хотя это будет тот еще головняк :( ) :D
а чем кастинг плох?
нужен не type hinting, а interface hinting.
А его разве сейчас нету?
<?php
interface ITest {
function test();
};

class testImp implements ITest {
function test() {
echo("ITest::test() was called!");
}
};

class T {
function testing(ITest $t) {
$t->test();
}
};

$test_class = new T();
$test_class->testing(new TestImp); // Здесь всё нормально
$test_class->testing("123"); // Fatal error. ITest needs, string given.
или я вас неправильно понял?
угу, я имел ввиду нечто вроде: function( $stylus: [ IPointer, IPen, IResetter ] )
Всю жизнь пхп был без строгой типизации, а тут на тебе, потрясение устоев...
Я вчера в классе поставил type hint на входящий параметр метода, string $result, так оно мне начало ругаться на instance of string passed, expected string...ну ее нахер, такую типизацию...
если честно достали уже деланьем с ПХП какогото мега ООПНОГО языка, ПХП всегда был и должен оставсться шустрым серверным скриптом на котором достаточно быстро можно что то написать а также можно написать достаточно долго и серьезно. ООП в пхп имеет смысл быть по моему мнению но степень этого смысла ниже чем например ООП в С++ или AS3 и не нужно наворачивать еще и это
type hinting нужен, причем в том чилсе для пользовательских типов. Это пригодится в первую очередь для реализации ORM. Так как позволит интерпретатору знать тип переменной. Сейчас для сохранения информации о типах приходится использовать дополнительные массивы или даже хранить их в базе.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории