Pull to refresh

Comments 98

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

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

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

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

и еще бы overloading на основе хинтинга (хотя это будет тот еще головняк :( ) :D
А его разве сейчас нету?
<?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. Так как позволит интерпретатору знать тип переменной. Сейчас для сохранения информации о типах приходится использовать дополнительные массивы или даже хранить их в базе.
Sign up to leave a comment.

Articles