Objektové literály v PHP

Školení, která pořádám

JavaScript nemá asociativní pole a místo nich používá objekty. Proto je velice praktické, že pomocí syntaxe { vlastnost1: hodnota, vlastnost2: hodnota } dovoluje jejich přímé vytváření. PHP asociativní pole má, ale i tak by se nám někdy mohla hodit možnost si stejně snadno vytvořit objekt. Dá se k tomu použít tato syntaxe:

<?php
$obj = (object) array("vlastnost1" => "hodnota", "vlastnost2" => "hodnota");

// tradiční přístup
$obj = new stdClass;
$obj->vlastnost1 = "hodnota";
$obj->vlastnost2 = "hodnota";
?>
Jakub Vrána, Výuka, 12.3.2007, diskuse: 24 (nové: 0)

Diskuse

ikona MiSHAK:

Další zkratka do sbírky :) Přetypovávat array na object mě ještě nenapadlo.

ikona Kalda:

Jen jedna drobnost - není to rýpání do obsahu článku, jen upozornění pro některé čtenáře.
ECMAScript specifikace neobsahuje asociativní pole, ale "klasický JavaScript", jak jej zpracovává např. IE nebo Firefox, umí s asociativním polem pracovat, což ale kromě obcházení standardu přináší i další úskalí...

ikona Jakub Vrána OpenID:

A jak se s tímto asociativním polem pracuje?

ikona Kalda:

Jednak to občas naleznu ve "článcích pro začátečníky": http://www.webmonkey.com/webmonkey/98/29/index1a_page6.html

Trošku užitečnější bude zřejmě toto: http://www.andrewdupont.net/2006/05/18/javascript-…-considered-harmful/

ikona Jakub Vrána OpenID:

Ve skutečnosti to tedy asociativní pole není, jenom to tak trochu vypadá. Třída Array je odvozena z třídy Object a jako takové jí lze přidávat další vlastnosti a metody k těm stávajícím (např. length).

ivan_d:

Jaké výhody by mohla mít tato konstrukce? Nebo zná někdo případ reálného použití?

ikona Jakub Vrána OpenID:

Já jsem objektové literály použil v projektu PHPExcel. Pro získání stylu buněk existují dva způsoby: Buď přímo pomocí SimpleXML přes $xmlStyles->dxfs->dxf nebo je nutné si je poskládat z číselníků jako např. $xmlStyles->fonts->font. Aby se s tím dalo jednotně pracovat, je vhodné to převést na stejný typ.

ivan_d:

Aha, chcete tím říct, že to lze využít pro vytvoření objektů, které nějaká knihovna používá výhradně prostřednictvím properties? Tedy něco takového:
<?php
$o
= (object) array(
  "color" => '#ffffff',
  "fonts" => (object) array('font' => 'Arial')
);
?>
To možná stojí za zamyšlení - podstrčit jinak za složitý objekt něco jednoduššího.

Trochu mi to připomíná rozhovor s jedním programátorem (myslím, že to byl Guido van Rossum), který říkal, že pokud se rozhodnu přijímat parametry jen určitého typu, může to být jen moje omezenost. A někdo jiný může umět využít moji funkci jinak.

Díky za typ - asi bych to necpal, kde to snese, ale může se hodit. Možná by obecně u některých triků pomohl konkrétnější příklad možného použití.

ikona error414:

> PHP asociativní pole má, ale i tak by se nám někdy mohla hodit možnost si stejně snadno vytvořit objekt.

Ted mam vytvoren objekt stdClass, ale ted co snim dal?
Jak nad tim mohu volat funkce pro praci s polem?

PIF:

Moc rozdílu mezi array a objektem, z hlediska nějakého datového uložiště není, takže bych využití rozhodně našel - když máme celou aplikaci ryze objektovou, tak by se takové přímočaré vytváření objektů, jakožto uložišť, mohlo hodit.

ivan_d:

Asi nechápu. Proč mít 'ryze' objektovou aplikaci? OOP mi dává výhody (zapouzdření, již 'vymyšlená' organizace kódu,...). Proto OOP používám. V čem je výhoda zde? (Kromě naparování se před těmi, co mi to budou baštit?)

PIF:

myslel jsem to spíše tak, že někdy máme data jen v poli a potřebujeme z nich udělat objekt.

paranoiq:

díky moc za radu. stdClass je defaultně přetížená? kde o tom najdu více?

ikona finc:

Moc jsem nepochopil, k čemu je to dobré. Navíc přistupovat k atributům třídy napřímo, také není zrovna dobře :)
Tohle je docela lámání někam, kde to ztrácí smysl.
Za pozornost spíše stojí implementace Iteratoru v PHP 5, ale to už je zase z trošku jiného soudku.

ikona Radek Hulán:

Dobré to je, napsat ["hodnota"] je mnohem delší než -> hodnota. Skoro bych řekl, že pracovní efektivita stoupne 2x! :)

Skvělý tip, netušil jsem, že PHP umí takto přetypovat pole na objekt.

PAtrik:

Neviem ci to nie je nebezpecna konstrukcia. PHP ma nasmerovane na objektovo orientovanost ala Java, a tak v buducnosti sa neda vylucit, ci tato konstrukcia nebude pouzivana na konvertovanie typu array na objekt odvodene z triedy Array.
Inac je to zaujimave ake veci sa daju v PHP robit :)

optik:

Ja to pouzivam docela casto, zapada to tak nejak do koncepce ruznych objektovych PHP frameworku a kdyz je pouzivam, pouzivam i tohle. Jen na okraj, ja jsem to nasel jiz pred delsi dobou primo v komentarich v manualu PHP - http://cz2.php.net/manual/en/language.types.object.php

Radek:

Ahoj,
sice je to trochu off topic, ale i tak. Objektovému programování teprve začínám přicházet na chuť až teď, ale i tak se mi zdá tato konstrukce trochu nezdařilá. Vidím to jako nedokonalost PHP v zapouzdření objektu. Až se to jednou napraví a objekty budou v PHP doopravdy zapouzdřeny, bude tento zápis chybný. Pokud se mýlím, vysvětlete mi to. Děkuji.

ikona v6ak:

No toto je spíš taková praktická pomůcka, skutečný objekt by měl být instancí nějaké pokud možno co nejkonkrétnější třídy. Ale někde se to hodí, spíš ale pro vnitřní struktury, kde to nedělá příliš nepořádku.

Megaloman:

Já bych to zase jako nedokonalost neviděl...

To, co píše v6ak "skutečný objekt by měl být instancí nějaké pokud možno co nejkonkrétnější třídy" je sice pravda, ale proč netvořit objekty za běhu, které jsou natolik primitivní, že co nejkonkrétnější třídu nepotřebují?

A není náhodou (object)array(...) jen instancí stdClass, což je konkrétní třída?

ikona v6ak:

Takže: třeba už v dokumentaci asi nebudeš psát, že metoda vrací stdObject... Prostě třída stdObject může být logicky skoro cokoli a nemá konkrétní logiku.
Prostě, hodí se to akorát pro malé použití: mám jednoduchý objekt, který si něco sám pro sebe uchovává (při komunikaci s okolím se to projeví v jiné formě - nějak to konvertuje). Je to celkem jednoduchá záležitost a psát na to třídu by bylo sice jednoduché, ale byla by to příliš velká investice na to, že na 99% se této obecnosti nevyužije. A v 1% případů bych zas tolik neztratit, akorát upravil krátkou třídu.

Megaloman:

No, to já se nehádám, v podstatě věci s tebou souhlasím, jen jsem reagoval trochu "hnidopišsky".

Na druhou stranu pokud potřebuji objekt, který má životnost třeba pár řádků kódu nebo potřebuji konvertovat pole na objekt, abych ho mohl předat jako parametr funkce, metody, tak proč ne? Většinou by takovéto řešení bylo někde zapoutdřeno uvnitř metody/funkce bez potřeby dokumentace...

ikona v6ak:

Vpodstatě jsem mluvil o tom, že v takových případech by to mělo být použitelné.

Megaloman:

Sry, moje chyba, špatně jsem pochopil tvůj předchozí příspěvek...

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2018 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.