k47.cz
foto Praha výběr povídky kulturatwitter FB


23. 3. 2012

PHP 5.4

       

Po téměř třech letech vyšla finální verze PHP 5.4, která přináší mnoho novinek. Tady jsou ty nejzajímavější.


Pole

Pole dostala novou kompaktní syntaxi:

[19, 5, 2013]
['Mortis Arytmia' => 7, 'Terminalita' => 41]

Konečně můžeme dereferencovat pole a už nemusíme laborovat s dočasnými proměnnými, když chceme použít jenom něco z vráceného pole

// postaru:
$ex = explode(',', $str);
$a = $ex[0];

// postaru, ale trochu vynalézavěji:
list($a) = explode(',', $str);

// nově:
$a = explode(',', $str)[0];

Ale na druhou stranu nefunguje identická konstrukce s funkcemi. Takže currying musíme nechat u ledu.

func($arg)($arg2)

Funkce

Konečně můžeme vytvořit objekt a hned na něm zavolat nějakou metodu bez rošád s dočasnými proměnnými.

(new Person)->runAway();

Přibyl nový typehint callable, který zahrnuje anonymní funkce (třída Closure), všechny objekty mající metodu __invoke, a pseudotyp callable ve formách "functionName", array($object, 'method') a array('Classs', 'method').

function map($collection, callable $f) { /* ... */ }

Syntaxe $f() funguje i když je $f pole ve tvaru array($obj, 'method'). Minulá verze PHP si v tomhle případě stěžovala a bylo se nutné uchýlit k obezličce call_user_func, která má mimořádný talent znepřehlednit kód (například v Atrox\Arr jsem na to rezignoval s tím, že věci v 5.3 můžou můžou zlobit).

Velkou novinkou je, že anonymní funkce definované v těle třídy mají přístup k proměnné $this aktuální instance. Nemusíme ji ručně importovat do scope funkce a navíc máme přístup k privátním členům objektu i jeho třídy, tedy přesně jako kdyby closure byla metodou třídy.

//dříve:
$self = $this;
function ($args) use($self) {
  return $self->method($args);
}

//teď:
function ($args) {
  return $this->method($args);
}

Třída Closure, která implementuje anonymní funkce, dostala novou metodu bindTo, pomocí, které můžeme změnit instanci na kterou je navázená proměnná $this uvnitř anonymní funkce. Nevím proč něco takového přidávali, protože se to dá velice snadno zneužít pro přístup k soukromým proměnným libovolného objektu bez použití reflexe.

class Person {
  private $name = "Karel", $surname = "Kalandra", $powerLevel = 9001;
}

$fuckEverything = function() {
  foreach (get_object_vars($this) as $prop => $val)
    $this->$prop = "U DUN GOOFED!";
};

$person = new Person;
$fuckEverything = $fuckEverything->bindTo($person, $person);
$fuckEverything();

var_dump($person); // U DUN GOOFED!

Traity

Poslední novinkou (a pravděpodobně tou největší v 5.4) jsou traity, které umožní znovupoužití kódu mimo strom dědičnosti. Nejde o žádné složitosti, jenom jazykem asistovaný copy-paste skupiny metod. Traity si s sebou nenesou žádný typ, nemají stav, neprobíhá žádná linearizace, takže se všechny konflikty se musejí vyřešit ručně a jeden trait nemůže "dekorovat" metody jiného traitu.

trait PropertyAsMethod {
  function __get($name) {
    return $this->$name();
  }
}

class Person {
  use PropertyAsMethod; // použijeme trait

  function runAway() {
    var_dump("Přes kopce a daleko, daleko, do Západních zemí.");
  }
}

$person = new Person;
$person->runAway(); // normálně
$person->runAway;   // funkcionalita získaná z traitu PropertyAsMethod

vstoupit do diskuze    sdílet na facebooku, twitteru, google+

publikováno 23. 3. 2012

příbuzné články:
Atrox\Matcher
Spellcheck
Operace Tripkodér
get_calling_class() pro PHP 5.2 📷
Scala - Booleovská kompozice funkcí 📷
Scala - konverze TupleN na case class 📷

sem odkazují:
Prog smetí

píše k47 & NEVERYOUNG, kontakt: ascii@k47.cz