Scriptorama.nl

Header image showing a keyboard, mouse, laptop and books on design patterns

Wenslijstje voor PHP6

Hoewel veel mensen nog bezig zijn met het migreren naar PHP 5, wordt PHP 6 ondertussen natuurlijk ook door ontwikkelt. De grote feature van PHP 6 zal de volledige unicode support zijn, maar er is natuurlijk nog ruimte voor meer.Stephan Schmidt heeft een aantal wensen voor PHP6 op een rijtje gezet:

Update: Ik claimde dat PHP5 al typehints had voor int, string, float etc. en dit is niet het geval. Aangepast. Thx daan ;-)

  • PHP5 heeft al typehints maar alleen voor scalars (int, string, float) specifieke klasse namen, interfaces en het type array. Stephan zou ook graag een 'object' typehint zien zodat hij kan aangeven dat een bepaalde functie of methode alleen een object kan ontvangen.
  • Stephan ziet ook graag Namespaces in PHP6, zodat je kunt ontwikkelen binnen een namespace en geen vreemde prefixes hoeft te gebruiken in je klasse namen. Namespaces zouden eigenlijk al in PHP5 komen, maar zijn vanwege technische problemen uitgesteld.

Persoonlijk zou ik graag zien dat de PHP group voor PHP6 meer aandacht gaat besteden aan het migreren. PHP 5 is al 2.5 jaar beschikbaar en er zijn nog steeds een hele hoop mensen die bezig zijn met PHP 4. Gelukkig staat dit ook op de radar van de PHP group, want in de Changelog van PHP 5.2.1 zien we:

Added forward support for (binary) cast. (Derick)

Dit is een van de nieuwe string types die in PHP6 geintroduceerd worden: er zijn unicode strings en binary strings. De details hiervan kun je vinden in Andrei's I love Unicode, You love unicode presentatie. Wanneer je al met unicode dingen bezig bent, kun je nu alvast aangeven wat een gewone binary string is en wat beschouwt moet worden als een unicode string en dat vergemakkelijkt straks de migratie naar PHP6.

Wat zou jij graag zien in PHP 6?

Reageer ook!

Zet scalar typehints maar ook op het verlanglijstje. :P

"Stephan zou ook graag een 'object' typehint zien zodat hij kan aangeven dat een bepaalde functie of methode alleen een object kan ontvangen."

Het kan zijn dat ik het verkeerd begrijp, maar dit is gewoon mogelijk:

Mja je zou bijvoorbeeld een interface kunnen maken en die de naam `Object` kunnen geven, maar dat is ook niet ideaal.

Ik ga idd ook voor de typehints, maar dan wordt php weer een beetje een sterkgetypeerde taal en dat was volgens mij toch niet helemaal de bedoeling dat ik een keer gelezen heb @ comments van php medewerkers.

- namespaces
- migrate.php.net: migratie-handleiding voor hosters en gebruikers

En in de categorie 'pipe dream':
- lambda functions zonder eval()/create_function() ongein
- named function parameters
- operator methods
- array shorthand: [foo: 'bar', bar: foo], [1, 2, 3]
- arrays als objecten
- throw shorthand voor single catch statement: throw 'foo' wordt automagisch throw new Exception('foo')

@Iwan:

> dan wordt php weer een beetje een
> sterkgetypeerde taal en dat was volgens mij
> toch niet helemaal de bedoeling dat ik een keer > gelezen heb @ comments van php medewerkers.

De mogelijkheid tot typehinting is natuurlijk geen verplichting tot het gebruik ervan.. Dus ik zie geen belemmeringen..

Ik ga ook voor het migratie stuk. Dat is het grootste probleem met php5.

Mogelijkheid om te verwijzen naar DE child vanuit de parent:

Ik krijg dit maar niet voor elkaar.

Stephan Schmidt heeft er inmidddels nog 1 gepost:

http://www.stubbles.org/archives/8-My-wishlist-for-PHP-6,-pt3-Annotations.html

@Koen: in wat voor context zou je dat willen gebruiken dan? Klinkt eerder als iets waar een design verbeterd kan worden :)

Ik poste een voorbeeld code maar die werd blijkbaar genegeerd. Nog ens proberen:

-----
class ParentClass {
public static function calledViaChild() {
return child::$_protectedVar;
}
}
class ChildClass1 extends ParentClass {
public static $_protectedVar = "foo";
}
class ChildClass2 extends ParentClass {
public static $_protectedVar = "bar";
}

echo ChildClass1::calledViaChild(); // foo
echo ChildClass2::calledViaChild(); // bar
------------
Zoiets is momenteel nog niet mogelijk voor zover ik weet.

Lees de handlijding is man :)
Kan dus wel!

Als je een class overneemd dan worden die parent functies onderdeel van het child.

Dus als je op de child een functie uitvoerd van die komt van de parent dan ziet die functie gewoon de parent en child als een.
Alleen is het zo dat als de child een var of functie heeft die het zelfde heet als die van de parrent dan word die van de parent overschrijven maar kan je nog wel met parent:: aanroepen.

Of zo iets, in het donken typen met een zwarttoetsennboord naar niet samen :)

Koen bedoelt juist iets anders. Hij wil wanneer hij een overervende klasse heeft gemaakt vanuit de Parent een nieuwe waarde van de Child uitlezen. Een soort bi-directionele inheritance.

Dat gaat uiteraard niet gebeuren. Het idee is juist dat een overerfende klasse de parent uitbreidt. En niet dat de parent op wijzigingen in de childs bouwt.

Ik vraag me dan ook af in wat voor situatie je dit uberhaupt zou willen gebruiken :)

Een voorbeeldje, bij een Model klasse die geen databasekolom maar een databasetabel voorstelt:

Ik maak hier gebruik van de fictieve constante 'child'.
(even aannemen dat self::$_db is geset in een soort van 'init' methode)
----
class DP_Model {
public static function add($data) {
self::_filter($data); self::$_db->insert(child::$_table, $data);
}

public static function update($data, $where, $quoteInto = array()) {
self::_filter($data);
self::$_db->updata(child::$_table, $data, $where, $quoteInto);
}

public static function delete($id) {
self::_filter($data);
if(child::$_hasDeleteColumn) {
self::$_db->update(child::$_table, array('deleted' => 1), 'id = ?', $id);
} else {
self::$_db->delete(child::$_table, $id);
}

public static function recover($id) {
if(child::$_hasDeletedColumn) {
self::$_db->update(child::$_table, array('deleted' => 0), 'id = ?', $id);
} else {
// error throwen of iets dergelijks
}

protected static function _filter(&$data) {
$data = array_intersect_key($data, array_flip(child::$_columns);
}
}
-----

En dan zal je heel toffe klassen hiervan kunnen extenden:

-----
class User extends DP_Model {
protected $_table= "user";
protected $_hasDeletedColumn = true;
protected $_columns = array('username', 'first_name', 'last_name', 'email', ...);
}

class ForumPost extends DP_Model {
protected $_table = "forum_posts";
protected $_hasDeletedColumn = true;
protected $_columns = array('owner', 'body_id', 'created');
}
-------

==>

-----
User::add(array('username' => 'a username', 'first_name' => 'Koen', 'last_name' => 'Speelmeijer', 'email' => '...', 'aNonExistantColumn' => 'value');
// die laatste wordt dan genegeerd
ForumPost::delete(5);
// enz enz enz
-----

Nu moet ik het zo doen:
----
User::instance()->add(....);
----

Is er trouwens een ubb code voor codes, omdat het er nu niet uitziet.
Hier heb ik ook even de code gepost voor de uitleining:
http://v2.pastebin.be/188

"Dat gaat uiteraard niet gebeuren. Het idee is juist dat een overerfende klasse de parent uitbreidt. En niet dat de parent op wijzigingen in de childs bouwt."

Hier ben ik het trouwens niet mee eens omdat bij 'niet-statisch' klassen dit wel zo gebeurd. Dit is volgens mij hetgene waar polymorfisme op gebasseerd is als ik me niet vergis. Dat de parent aan child members kan.

Het idee van polymorfisme is dat je de Childs kunt aanspreken alsof ze hun Parent waren. De parent is nml de lowest common denominator.

Om even verder op jouw idee te bouwen:

PHP:
  1. class ModelProcessor
  2. {
  3.   function Process(DP_Model $model)
  4.   {
  5.     $model->delete(5);
  6.   }
  7. }

Op de manier kun je alle instanties en childs van DP_Model aan ModelProcess::Process() voeren. Alle childs van DP_Model hebben immers de methodes die DP_Model aanbiedt.

Ik ben sowieso niet zo'n fan van statische methodes zoals jij ze gebruikt aangezien je op deze manier een stuk flexibiliteit inlevert. Want, wanneer je User::add() gebruikt, is je code hard gebonden aan de user klasse en dat is niet altijd gewenst.

Je kunt overigens [ php ] [ /php ] gebruiken voor PHP code.

Het idee achter overerving is nu juist dat je subklassen kunt toevoegen zonder dat de parentklasse daar iets van af weet. Dit heeft te maken met herbruikbaarheid, een belangrijk punt uit de OOP. Als je kennis over children in de parent zou opnemen, moet je voor iedere wijziging in de childklasse ook de parent aanpassen (tenminste als de interface wijzigt). Het idee is juist dat dat niet moet.

Polymorfisme is inderdaad het concept dat je een subklasse kunt benaderen alsof het een klasse van het type van de (een) parent is.

Voorbeeld:

interface Writeable {
public function save();
public function load();
}

class Parent {
...
public function doeJeDing() {
}
...
}

class Child extends Parent implements Writeable {
...
}

// main code
$oDing = new Child();
// dit mag nu
doeIetsMetWriteables($oDing);
// maar dit ook
doeIetsMetParent($oDing);

// functies die polymoprfisme gebruiken
function doeIetsMetWriteables(Writeable $p_oObject) {
$p_oObject->save();
}

function doeIetsMetParent(Parent $p_oObject) {
// doe iets
}

Leave a comment
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>