Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Вызов методов и доступ к свойствам создаваемого объекта — без скобок не понятно, вызывается ли метод свежесозданного объекта или же создаётся объект класса, имя которого возвращает вызванный метод (какая-нибудь хитрая фабрика)Штоа? Какая ещё хитрая фабрика? В PHP new bar() вернёт экземпляр класса bar, по-другому это не работает.
class foo {}
function bar()
{
return 'foo';
}
$fooClass = bar();
$foo = new $fooClass;
class foo {}
function bar()
{
return 'foo';
}
$fooClass = new bar();
class foo {}
function bar()
{
return 'foo';
}
$fooClass = new bar()();
$x = ('cos')(20)
$prop = $obj -> ('property name' . $i); // почему заюзали { .... } вместо ( ) не очень понятно, т.к. -> похож на бинарный оператор.
...
и т.д. и т.п.
class foo {}
$foo = new foo;
class foo {}
$foo = new foo();
class foo {}
define('bar', 'foo');
$fooClass = new bar();
$a = 'new';
$b = $a bar();
...$params
меня ещё в ruby это пугало, когда приходится считать аргументы, чтобы узнать какие переданы.
$a || $b && $c в нормальной команде этот код не пройдёт код ревью пока скобки не расставят
if($error_type&E_PARSE)
return 'This is parse error';
if($error_type==E_PARSE)
return 'This is parse error';
if(((($error_type===E_PARSE))))
return ((((string)'This is parse error'))); //Я не уверен, что это строка, пожалуй стоит проверять ещё и при каждом использовании функции
главное, чтобы код был понятен всем
Вот вы привели ссылку на приоритеты, покажите где на ней написано, что приоритет new выше чем у вызова функции?
и тем более if (!$bar = foo()), этот код работает как if (! ($bar = foo()) )
хотя приоритет у "=" меньше чем у "!"
Замечание:
Несмотря на то, что оператор = имеет низший приоритет, чем большинство остальных операторов, PHP все равно позволяет использовать следующую конструкцию: if (!$a = foo()), которая присваивает переменной $a результат выполнения функции foo().
я лично думал что будет нотис и мне не стыдно
php -r "print true ? 1 : true ? 2 : true ? 3 : true ? 4 : 5;"Какой результат будет у следующего выражения?
php -r «print true? 1: true? 2: true? 3: true? 4: 5;»
Я вот про это поведение узнал только из документации.
Знание приоритетов не гарантирует отсутствие случайной ошибки
нормальные программисты разбираются в коде и без всяких IDE
Ну и бородатая хотелка — полный тайпхинтинг в php стиле, с приведением. function foo(int $id, string $default = '') {}
Переопределение списка аргументов… даёт полную ясность того, что конкретно реализовывает метод, делает код более чистым, избавляя от каскада if-else
class B {
function foo() { func_get_ars(); }
function foo($bar = null) { func_get_ars(); }
}
$o = new B;
$o->foo(1, 2); // Unpredictable call
...$params BC break тоже будет?func_get_args() вызывается в методе, который имеет «брата» по названию в данном классе, то генерим ошибку. class foo {
public static function bar($optional = false){
return $optional;
}
// как бы перегруженный метод, в том же классе или наследнике
public static function bar(){
return true;
}
}
var_dump(foo::bar()); // ??? какой метод должен вызваться ???
Fatal error: Cannot redeclare foo::bar() ;-)var_dump($square->calcPerimeter(array(1, 1, 1, 1))); // 4
var_dump($square->calcPerimeter(1)); // 4
class Figure {
function calcArea(array $sides) { /* realisation */ }
}
class Square extends Figure {
function calcArea(int $side) { /* realisation */ }
}
/* У меня есть функция, использующая ваш код */
function area(Figure $f, $sides) {
return $f->calcArea($sides);
}
$square = new Square();
area($square, [1, 1, 1, 1]);
abstract class Figure {
function __construct($sides) { $this->sides = $sides; }
function calcPerimeter() { return array_sum($this->sides); }
abstract function calcArea();
}
class Square {
function __construct($side) { /* irrelevant */ }
function calcArea() { return $this->sides[0] * $this->sides[0]; }
}
class Polygon {
function __construct($sides, $angles) { /* irrelevant */ }
function calcArea() { /* большая формула, не помню, какая */}
}
interface calculated {
public function calcArea();
}
abstract class Figure implements calculated {
function __construct($sides) { $this->sides = $sides; }
function calcPerimeter() { return array_sum($this->sides); }
}
class Square {
function __construct($side) { /* irrelevant */ }
function calcArea() { return $this->sides[0] * $this->sides[0]; }
}
class Polygon {
function __construct($sides, $angles) { /* irrelevant */ }
function calcArea() { /* большая формула, не помню, какая */ }
}
class Calculator {
function __construct($name) { /* irrelevant */ }
function calculate(array $prices) { /* calculation */ }
function calculate(PriceCollection $collection) { /* calculation */ }
}
Когда дочерний класс реализует (переопределяет) метод из этого интерфейса, я ожидаю, что именно переопределенный метод и будет вызван в случае: $figure->calcPerimeter(/* args */).
надо будет определить в классе 2 метода с одним названием

class foo {
public $x = 1;
}
class bar {
public $y = 'foo';
}
$x = 'bar';
$bar = new bar;
var_dump((new bar)->y); // foo
var_dump((new $x)->y); // foo
var_dump((new $bar->y)->x); // 1
new foo()->xyz; — не вижу ничего поразительного. В нормально написанной грамматике не должно быть разницы, какое выражение использовать перед обращением к полю — вызов функции, литерал или создание нового объекта. Да и вообще, странная практика — создать объект и тут же потерять ссылку на него.default при вызове — уж лучше тогда добавить именованные аргументы, потому что это — неудобный костыль.deprecated — возможно. Единственная же реально полезная и правильная штука — это исключения вместо Fatal Error. Даже как-то странно, что это ввели только сейчас.Троеточие перед именем переменной — выглядит ужасно. Наверняка хотели сделать «как в Java, но не совсем».
String... params в Java. Можно было бы сделать $args... — было бы сильно лучше.return variable и return expr_without_variable. Почему переменная не является частным случаем выражения — тайна, покрытая мраком.default — то зачем сначала делать костыль, чтобы потом сделать как следует? Это же не срочная фича, без которой народ изнемогает, а если сделать сейчас так — то потом придется поддерживать оба варианта.Я согласен, что использование многоточия очевидно с точки зрения семантики, но оно хорошо смотрится в после идентификатора, а не перед ним. Например, String… params в Java. Можно было бы сделать $args… — было бы сильно лучше.
Это же не срочная фича, без которой народ изнемогает, а если сделать сейчас так — то потом придется поддерживать оба варианта.
Вы привыкли как в Джаве, вот вам и кажется, что так красивее.
params из C#, однако вариант с многоточием из Java мне все равно кажется более грамотным, хотя бы потому что очень часто хочется объявить функцию с аргументом params — а нельзя, ключевое слово.Вы привыкните через неделю и перестанете внимание обращать.
Когда я последний раз в нее заглядывал, там были отдельные правила наподобие return variable и return expr_without_variable. Почему переменная не является частным случаем выражения — тайна, покрытая мраком.
function(){
return array('x' => new MyObject());
}()['x']->method();
class foo {
public $x = 5;
public function bar() {
$this->x = 10;
}
public function baz() {
return $this->x;
}
}
var_dump(new foo()->bar()->baz()); // int(10)
$this в каждой функции, это сделать невозможно. Каждый следующий метод в цепочке вызывается на том объекте, который был возвращен из предыдущего. Как только вы перестанете возвращать $this, контекст потеряется.<?php
class foo {
public $x = 1;
public function getX() {
return $this->x;
}
public function setX($val) {
$this->x = $val;
return $this;
}
}
$X = new foo->setX(10)->getX();
var_dump($X); // int(10)
?>
Синтаксис 2 (со скобками)
(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]
Совместимость с E_RECOVERABLE_ERROR
Сейчас можно игнорировать восстанавливаемые фатальные ошибки, используя кастомный обработчик ошибок. Заменив их на исключения, мы потеряем такую возможность, ломая, таким образом обратную совместимость.
$str1->concat($str2) менее удобно было чем $str1 . $str2.create_query('deleted=0', 'name',,, true);
create_query и скажите, сколько времени вам понадобится чтобы определить, в какой по счету параметр передано значение true? if($a === null) {$a = true}
if($b === null) {$b = self::BLA_BLA}
function foo($var, ...$params)
{
...
}
function foo($var, array $params = array())
{
...
}
function foo($var, array $params = array())
{
...
}
function foo($var, array $params = [])
{
...
}
function fn($reqParam, $optParam = null, ...$params) { }
function fn($param1, $param2, $param3) { }
$args = [1, 2, 3];
fn(...$args);
$more_args = [2, 3];
fn(1, ...$args);
А то, что сейчас все перемешано — это одна из серьезнейших проблем языка.
srtlen($var); // тип может быть почти любой
((string) $var)->length(); // на фиг, на фиг ...
Это никому не нужно.
Но все методы для работы со строками привести к виду String::length() — вот это то, чего я хочу.
Не говорите за всех :)
Не вижу особого смысла. Почему не к виду \String\length()?
function create_query($where, $order_by, $join_type = '', $execute = false, $report_errors = false) { }
create_query('deleted=0', 'name', default, default, /*report_errors*/ true);
class B {
public function n ($a, $b = 456) {
return $a . $b;
}
}
class A extends B {
public function m ($a = 123, $b = default) {
return parent::n($a, $b);
}
}
$a = new A();
echo $a->m(); // 123456
echo $a->m(000); // 000456
echo $a->m(321, 321); // 321321
echo $a->m(default, 321); // 123321
Переопределение списка аргументов
Функции в PHP 5.6 — что нового?