Pull to refresh

Comments 127

Ну, от части это уже было реализовано ХЗ с какой версии, например для array.
Попытка впихнуть строку в объявленную таким образом функцию:
function test(array $arr) {};

вызывает:
Catchable fatal error: Argument 1 passed to func() must be an array, string given, called...


Странно, что не включили всякие проверки на int и string раньше.
Что самое смешное, на типизацию по int и string он тоже реагирует ошибкой. Вот только выдает это сообщение даже если ему подали нужный тип на вход. Сообщение о ошибке в этом случае выглядит очень смешно:
Catchable fatal error: Argument 1 passed to func() must be an instance of string, string given

Больше похоже, что это баг. В случае с int и string он просто криво делает сравнение типов.
Не, это не баг, int и string интерпретатор сейчас воспринимает как типизацию по классу, соот-но и ругается он на то что переданный аргумент не является экземпляром (instance) класса.
Вообще не понимаю, почему до этого момента этого не сделали, почему до сих пор эта функция будет вызывать Catchable error с текстом примерно такого содержания: "Variable must be instance of int, int given". Меня это поражает, честно говоря.
Этого, этого, это, это… Пора ложится спать…
Может потому что тип int в PHP — примитив?
Точно не могу сказать, но ранее отсутствовавшая возможность, описанная в топике, довольно удручала.
неужели PHP постепенно движется в сторону строгой типизации?
Да. И это здорово!
Вот только PHP6 релизнут и, тем более, поставят на большинство хостингов ой как не скоро. Это при условии, что scalar type hints не бэкпортнут в какой-нибудь PHP5.4.
Кстати, кроме этой функции в trunk ветке разработки PHP еще появился Array dereferencing. Стало возможным написание такого когда:
function foo() {return array(1, 2, 3);}
echo foo()[2];

class Foo 
{
    public function bar() { }
}

function func() 
{
    return new Foo();
}

func()->bar();


func()->bar(); уже давно можно, я постоянно таким пользуюсь, а вот echo foo()[2]; — да, не хватает)
Ога, шикарная вещь. Правда по-уродски смотрится такое обилие скобок.
Ну чо вот например контекст:

$dbTable->fetchAll()->toArray()[0];

или

$dbTable->fetchRow()['name'];

не так уж и уродски памом :)
Если нужен всего один ряд — то можно сделать fetchRow(), если одно поле — то выбирать в запросе одно поле и потом fetchCol(), fetchOne() или какие там методы в используемом вами DBAL
Выходит знач что вышеупомянутый синтаксис не нужен?
Это дело каждого: кому и как программировать. Лично я предпочитаю каждую специфичную задачу решать специфичным методом. Потому что это удобно. Вместо того чтобы плодить 1 метод который будет для всего подряд, даже того, что совсем сейчас нам не нужно.
Вы так и не ответили на вопрос, ну да ладно.
Я хотел показать пример когда синтаксис выглядит не уродски, а вы почему обратили внимание на то, что этот код делает.

если бы вместо названий переменных и методов было $foo и bar(), имел бы смысл ваш комментарий?
конечно имел бы, только он был бы более абстрактный. что-то вроде: «зачем писать методы, которые делают работы больше, чем этого требует задача»

вы ведь не пишете SELECT * FROM mytable всёгда только потому, что СУБД позволяет так делать. нет. вы выбираете только нужные поля, и, более того, указываете условия выборки в WHERE. так почему же с методами вы не руководствуетесь тем же самым?
Конечно же нужен. Из-за него сейчас приходится в собственном велоклассе работы с БД делать

->fetch()->columnname

вместо

->fetch()['columnname']

Вроде бы одно и то же, но если у нас имя колонки, к примеру, динамически формируется конкатенацией, приходится городить несколько строк, что уменьшает читабельность, засоряет глобальное пространство имен, ну и вообще выглядит некрасиво.
а так хочется написать лапшу в одну строчку?
После перла хочется все написать в 1 строчку :)
только хотел сказать что пхп сахарок уже ближе к руби… да не, передумал)
$dbTable->fetchAll()->toArray()[0];
dbTable.fetchAll.to_a[0];
какой вообще в этом смысл? зачем писать методы, которые делают работы больше, чем это требуется задачей. нужна одна запись — напишите метод, который возвращает лишь одну запись. не плодите godlike-методы/классы.
Ну вдруг нужны все и с первой чото сделать.
«Вдруг» — это не подход программистов. Если вам нужна только первая запись — пусть метод возвращает только первую. Если нужны все — получайте все и обрабатывайте первую вместе с остальными.
Окай, опустим слово «вдруг» (смысл не меняется) :)

Нужны все, а первая нужна особенно для передачи другому методу.
Если вы будете что-то передавать в один метод — значит у вас уже есть переменная. Значит вы можете обратиться к переменной и выбрать оттуда всё, что нужно.

А с вашим предложением метод придётся вызывать дважды:
1. для получения только первого ряда
2. для получения вообще всех
В руби приводить к массиву не нужно :) Там, где надо, уже определен метод []
вот! этого как раз и не хватало.
при чём здесь второй пример с классами? этот код будет работать даже в пхп 4 (если убрать модификаторы видимости)
Простите, ошибся и скопипастил не тот код.
да, foo()[] очень нехватает, как минимум избавит от лишней строчки кода при выборке из базы
Я думаю, что строгая типизация в PHP — лишнее, а описанное в топике нововведение скорее похоже на синтаксический сахар для автоматического выбрасывания исключения при проверке типа входных аргументов. А вот фичу foo()[1] я давно ждал.
Строгая типизация лишняя в такой форме:
int $q = 5;
А то что параметры в функции будут проверяться это хорошо, это как минимум может избавить от кучи проверок, заменив их одним отловом нужного исключения
Мне всегда казалось, что не строгая типизация в пхп это его фишка. Если они от нее откажутся, они угробят язык. Они просто добавят возможность жестко типизировать некоторые моменты, а суть типизации в пхп, думаю, останется такой же.

Они лучше бы в пхп6 добавили многопоточность, 21 век на дворе, а такой главной вещи не существует…
А C# в сторону динамической — где-нибудь на середине встретятся.
C# больше к Ecmascript движется. Вот, например, удобнейшие динамические и анонимные классы мне представляются более удобными, чем ассоциативные массивы в PHP.
В пхп есть динамические классы, которые сейчас позволяют динамически добавлять свойства, в пхп6 появятся анонимные функции, и из этих динамический свойств можно будет делать методы… так что по сути это одно и то же, в Ecmascript все методы обьекта — свойства содержащие код :)
Анонимные функции есть начиная с РНР 5.3.0.
Смысл моего камента не в том когда появились анонимные функции
C# в сторону выведения типов и надеюсь до динамической они никогда не дойдут.
Ни в коем случае не надо путать такие аспекты типизации как строгость/нестрогость и статическая/динамическая типизация! В некотором смысле любой язык обладает нестрогой типизацией (вспомним неявное преобразование целых чисел в числа с плавающей точкой). У C# так вообще с первой версии есть такая штука как неявное преобразование типов (любых, до которых дотянутся кривые руки программиста). Движение в сторону «динамичности» — это больше для бесшовной интеграции с языками с динамической типизацией. Кстати, надо сказать, что там динамическая типизация есть ещё с первой версии: reflection никто не отменял. А вот в PHP элементы строгой типизации начали появляться ещё с тех пор, как появилась возможность задать тип параметра у функции/метода (тогда ещё класс, а не примитивный тип, кажется это появилось в 5 версии).

Что по мне, так ситуация неясна. Сегодня они добавили примитивный типы, завтра добавят возможность аннотировать (или уточнять) тип в любом месте, послезавтра добавят generics и получится Java или C#, только с кучей исторических костылей. Может, оно того не стоило? Может, сразу следовало везде пихать JSP и ASP.NET?
Вот представим, что у нас есть следующая декларация:
function check_counter( int $counter)
{
return;
}

А ещё есть параметр, который мы получаем таким вот образом: $_GET['counter']
Что произойдёт при попытке вызвать check_counter($_GET['counter'])?

Также не стоит забывать, что и из баз данные приходят в виде строк исключительно.
Вызывайте check_counter(intval($_GET['counter'])) и не гадайте на кофейной гуще.
1. тогда уж (int)
2. т.о. удобный скалярный тайп-хинтинг приведёт к раздуванию клиентского кода, правильно?

ps: я не гадал, я задал вопрос о том, как поведёт себя пхп — произведёт неявное преобразование типов или вывалит ошибку к тем, у кого на руках есть собранный из транка php
UFO just landed and posted this here
2. в явном виде — совсем не факт. к тому же, даже если у меня и написано — то сделать преобразование единожды в теле функции куда более элегантный вариант, чем делать это 100 раз в каждом из мест вызова. согласны?

ps: почему нельзя? '5' отлично неявно преобразуется, а вот для объекта можно и выкинуть эксепшн. так что «вот поэтому» — совсем не аргумент. неявное преобразование потому и неявное, а в пхп до сих пор типизация как была динамической, так и останется таковой, вне зависимости от скалярного тайп хинтинга.
так что вопрос открыт. жду ответа от тех, кто кроме размышлений таки собрал транк.
UFO just landed and posted this here
А вот тут пардон, а блоге Schlüter'а действительно поведение указано другое.
Удобный скалярный тип-хинтинг приведёт к более качественному описанию интерфейсов и проверки входящих данных.
собственно могу повторить в третий раз — как поведёт себя пхп, если ему передадут '5', к примеру?
Можешь не писать foo(int $a). И быть счастливым.
я много чего могу писать. только вот зачем комментировать мой комментарий, если вы не в состоянии ответить на вопрос, который в нём содержится?
Будет Catchable fatal error.
Zerkms — не ожидал от тебя что будешь минусовать оппонента.

Mr. Mot он же BeGeMoT.
Я знаю кто ты :-)
Поставил минусы за ответы, не относящиеся к вопросу и попытку простебать «оппонента»
Вот интересно где же тут стёб…

Когда говорится о том, что при создание интерфейс более чёткая типизация параметрво функции лучше, чем без типизации.
ты меня прекрасно знаешь, чтобы понимать, что я это отлично знаю, и что мне этого напоминать не нужно :-) — я задал вполне конкретный вопрос: как пхп будет себя вести в конкретной ситуации, и аналогично ожидал вполне конкретного ответа, а не философию, какой тайпхинтинг молодец :-)
Если ответа не знаешь, прочитаё ещё раз топик. Там чётко описанно что будет.
wiki.php.net/rfc/typecheckingweak

беге, ну чего же ты такой невнимательный и доверчивый? )))
в топике написана неправда, не всегда там будет еррор.
Ну так минусуй топик стартера за обман.
ТС не виноват в том, что не в состоянии перевести нормально :-)
Я минусовал не за неправильность, а за неспособность/нежелание ответить на мой вопрос и попытки меня научить неизвестно чему, вместо этого
кстати отбой, ТС молодец, всё правильно, а вот я балбес и не умею читать.
Ага, а мне минусы остались =)
кстати минусы не все мои! :-S
остальное уже наставили нам за «дискуссию»
UFO just landed and posted this here
спасибо за ответ.
Очевидно, бросит исключение.
Но, как говорит ссылка выше, приведет к инту. Я считаю, это неправильно.
1. ссылка выше устарела
2. будет Catchable fatal error, который не исключение
Тогда хорошо. Под исключением я подразумевал то, что надо.
Смотрим var_dump($_GET['counter']) и радуемся :)
Если согласно значению он выбирает тип — прислали число — ошибки нет, прислали текст — возникла ошибка.
Если всё string — пользуем (int)$_GET['counter'] при вызове или не пользуем int $counter в декларации.
Вы писали пост из предположения, что я не могу посмотреть тип переменной?
Я как раз и пишу, что из-за модификаторов код превращается в лапшу.
Согласно текущей реализации я обязан так писать.
Не понимаю — почему было не сделать неявное преобразование, как и везде в пхп?

Жёсткая типизация в этом исключительно месте при слабой типизации во всех остальных — это очередная насмешка над языком программирования.
try
{
    check_counter($_GET['counter'])
}
catch( Exception $e )
{
    // wrong type
}


=)
исключение не будет выброшено
Ну наверно это имеется ввиду в паре с обработчиком ошибок, выкидывающим ошибки в виде исключений.
Нет, не имеется, я протупил :(
PHP движется в сторону строгой типизации…
Но не её ли отсутствие обеспечивало такую популярность PHP?
Это не строгая типизация, это всего лишь валидация типов параметров в функции. Строгая типизация появится, когда нельзя будет с типами обращаться как попало — что и являлось одной из причин популярности (плюс, конечно, отличная документация).
насчет «отличной» документации не уверен… такие там перлы видел когда-то…
Шутите? В тот момент это была совершенно идеальная документация, с примерами использования практически всего. Можно было начинать программировать, вообще не зная ничего.
В «тот» момент — может быть. Но сейчас — не согласен. Сейчас описание функции а потом миллионы комментариев (в основном индусов) о том что так как написано не работает, но работает вот так…
Хотя с примерами, конечно :)
Так мы и говорим про стартовый момент. В то время это было очень просто, необычно и понятно. В отличие, например, от перла.
UFO just landed and posted this here
Наверное, Вы правы. Я уже года 2 на PHP не пишу, но до сих пор вспоминаю впечатления когда читаешь статью в документации и там написано что при таких то входных данных функция вернет то-то, а при других возвращаемое значение не определено
я, кстати, имел ввиду что это именно движение к строгой типизации.
Может постепенно хотят к ней прийти — чтоб народ не разбежался сразу :)
Согласен, да.
Без строгой типизации теперь все наши вызовы функций превратятся в лапшу вроде:

some_method((int)$_GET['i'], (float)$_GET['f'], ...)
Я так понял это будет проверка времени исполнения т.е. писать можно как угодно, а вот в момент вызова будет проверяться.
Будет проверяться естественно в рантайме, но вы не согласны, что с кучей модификаторов код превращается в лапшу?
Согласен. Так было в Яве до 1.5 с коллекциями

someMethod(((String)list.get(i)));
Вот именно. Лучше уж было добавлять скалярные типы в тайп хинтинг, при этом оставляя все преимущества слабой типизированности и как следствие — неявных преобразований.
Ну мне сложно говорить что было бы лучше для PHP — основная причина по которой мне сложен PHP — как раз отсутствие строгой типизации. Я слишком привык на нее полагаться и поэтому мне сложно писать свой PHP код (к счастью это надо раз в год) и сложно разбирать чужой.
Но думаю это сугубо личная заморочка. Все таки 20 лет написания программ на языках со строгой типизацией формируют привычку :-) Если динамическая типизация так популярна значит в ней есть смысл, но увы мне его не понять :-)
Еще бы типизацию значений возвращаемых функцией добавить — было бы просто отлично.
Тогда php-код станет чистой Java, в общем-то. Сам на неё окончательно ушёл.
И я (уже писал выше). Ибо когда попробовал кодить в Netbeans на PHP и на Java, то оказалось, что статически типизированный язык даёт больше возможностей (гораздо больше) для IDE в плане помощи программисту. Да и скорость Java сильно радует, опять же, в сравнении с.
Хм… скорость?
Меня радует скорость PHP для тех задач, для которых его обычно используют.
А вот скорость Java меня обычно не радует, или его часто используют не для тех задач, для которых он предназначался.
Те же Eclipse и Netbeans ужасно тормозят порой. Не помню, чтобы тормозил тот же QTCreator.
Я в своё время переключился на Java именно из-за скорости. По сути, на каждый php-запрос к сайту приходится устанавливать соединение с БД (они же вроде не кешируются?), какие-то структуры вынимать из кеша и так далее. Единственное что порадовало — всякие opcode-кеши, хоть код не надо каждый раз интерпретировать. В Java же всё это существует постоянно и на каждый запрос осуществляется минимум телодвижений.
UFO just landed and posted this here
appserver-in-php да, ещё стоит упомянуть phpdaemon и hiphop. Их отличие в том, что web-сервер встроен неподсредственно в них, поэтому не надо переинициализировать фреймворки, подключения к базам данным, структурам.
Но вот php-ftpm — не полноценный fastcgi сервер, при каждом запросе приложение заново инициализируется.

Но стоит упомянуть, что под вышеперечисленные appserver'ы пока ещё нет даже ни одной CMS (во всяком случае ещё недавно не было), то есть это настолько нишевое решение.

Для freeAKK — коннект к базе данных, который обычно кэшируется mysql (размер задаётся thread_cache_size в конфиге) — это такая ерунда на фоне подключения фреймворка или загрузки конфигов.
php-fm — «правильная» во всех смыслах этого слова реализация fastcgi и в 6 версии она будет встроена в ядро, как и apc кешер… не знаю как вы, а я жду от 6-ки очень больших результатов, особенно если ее оптимизируют по скорости
Вообще-то php-fpm есть в последнем релизе: php-5.3.3.
От 6ки я больше всего жду UTF!
Еще очень жду Traits и надеюсь, что они появятся раньше 6ки.
Я как бы даже не думаю о том что не будет полной поддержки UTF, без нее будет полное разочарование, даже со всеми его плюшками
я 5.3.3 еще не ставил, так что не знал, но в любом случае 5.3 — демо 6-ки :)
Какое же оно демо? Вполне стабильная версия. Использую на серверах. Работает безотказно.
Ну, я не так выразился, я имел ввиду что на 5.3 они тестируют то что будет в 6-ке, учитывая максимальную совместимость
5.3.3 испльзуем в Production — все Ок.
А QTCreator написан на PHP?) Хотя по некоторым тестам (третий вид лжи), Java иногда может обгонять С++.
Я не сказал, что QTCreator написан на PHP. На C++(QT) он и написан.
Хм…
Действительно? А ткните носом в ссылку/приложение, где Java обгоняет плюсы? Правда очень интересно!
Ну это я к тому, что в контексте сравнения скорости Java и PHP, заявление о том, что в отличии от Eclipse, QTCreater не тормозит, звучит странно. :-)

kano.net/javabench/ — вот тут, например, заявляют, что в некоторых тестах ява быстрее :-) Уж не знаю, то ли врут, то ли на плюсах писать не умеют.

www.freewebs.com/godaves/javabench_revisited/ — а здесь повторение вышеуказанного теста. Тут, на мой взгляд, результат более реалистичный.
А почему Java не может обогнать C++ ну, например, на любых вычислительных задачах, задачах ввода/вывода, задачах обработки (большого объёма) данных и т.д.? Не вижу ни одной причины.
Причина в том, что Java делает это через виртуальную машину.
C/C++ делают это напрямую, через libc
Бррр… Причём тут виртуальная машина и стандартная библиотека си? Виртуальная машина медленнее библиотеки?) Или речь всё же о нативности выполняемого кода?
В конечном итоге в Java выполняется такой же нативный код, не транслируется же. Имеются некоторые оговорки (которыми в случае нарочного замера скорости выполнения можно пренебречь), но в целом разница в скорости выполнения самого кода сравнима, что и показывают вышеупомянутые тесты. Программу на c++ проще соптимизировать под нативные условия — это да.
Sign up to leave a comment.

Articles