ugrás a tartalomhoz

Foreach, osztályok, publikus adattagok

therest · 2012. Jan. 11. (Sze), 16.59
Adott egy egyszerű osztály:

class cPerson {
	public $first;
	public $last;
	function __construct($first,$last) {
		$this->first=$first;
		$this->last=$last;
	}
}
Ha simán példányosítom akkor működik ahogy kell, tehát $instance->short -on keresztül elérem az adatot.

A gondom azzal van ha párat bepakolok egy session tömbbe:

$_SESSION['persons'][]=new cPerson('valami','név');
$_SESSION['persons'][]=new cPerson('másik','név');
A későbbiekben szeretnék végig menni a tömbön, és a publikus tagokat elérni:

foreach($_SESSION['persons'] as $person) {
  echo $person->first . ' ' . $person->last . '<br />';
}
Üres stringeket ír ki. Ha megnézem a cikluson belül $person-t var_dumppal, akkor látszik hogy benne van az adat, de nem tudom elérni.
Mitől lehet ez?
 
1

Nem osztaly

janoszen · 2012. Jan. 11. (Sze), 17.20
Ha nem osztalyt teszel bele, akkor mukodik? A notice-okat ugye bekapcsoltad?
2

Notice van, sima változókkal

therest · 2012. Jan. 11. (Sze), 17.45
Notice van, sima változókkal működik. Var dumpban azt mondta, hogy object(__PHP_Incomplete_Class). Ebből kiindulva azt kaptam, hogy a php fájlt ami az osztályt definícióját tartalmazza még a session elindítása előtt include-olni kell.
Így már működik is, csak a fejem felett világít egy hatalmas kérdőjel.
3

Nem értem ezen mit kell

MadBence · 2012. Jan. 11. (Sze), 17.57
Nem értem ezen mit kell csodálkozni, a session_start() (feltehetően, én nem ismerem a belső működést) visszaállítja a sorosított session állományt a php adatszerkezetére, és nyilván ha kap egy ismeretlen osztályt, akkor nem tudja, hogy most mit is akar ez jelenteni.
4

Én sem ismerem a belső

therest · 2012. Jan. 11. (Sze), 18.25
Én sem ismerem a belső működését, sőt szerializációval sem kell foglalkoznom általában, ezért a "visszaállítja a sorosított session állományt a php adatszerkezetére" több mint homályos számomra.

Ha látja az osztálystruktúrát, márpedig a var_dumpban, helyesen van minden, akkor miért __PHP_Incomplete_Class, $_SESSION['x']=new myClass('helló'); esetében, és miért van rendben $x=new myClass('helló'); esetében.

Ha valaki megvilágítaná, válasszal, linkkel, megköszönöm.
5

Legyen

MadBence · 2012. Jan. 11. (Sze), 18.49
Legyen a.php:
session_start();
print_r($_SESSION);
$x=new B();
include('b.php');
$_SESSION['x']=new B();
b.php-ben pedig legyen definiálva a B osztály.
A harmadik sor fatal errort dob, mert az include még nem futott le, a PHP nem tudja mi az a B osztály.

A session_start() valami olyasmit csinál, hogy megkeresi az adott munkamenet adatait (valahol), és lefuttat egy unserialize() szerű dolgot. Mivel nem találja a B osztályt (mert még nincs), ezért menti a menthetőt ezzel az incomplete class módszerrel. Nem tudom hogyan tárolja szerializáltan az adatokat a php, de ezek szerint tudja hol van az eleje, a vége az objektumnak, sőt az egyes adattagok neveit is fölismeri.

A B osztály definíciója azért kéne, hogy tudja mit csináljon (mit hívjon meg), ha egy metódust meg akarsz hívni.

Ha a B osztály csak később lesz látható a php számára, akkor ő azzal már nem tud mit kezdeni, nem fogja hirtelen felismerni, hogy hoppá ez itt egy B típusú objektum volt, neki az már incomplete class marad.
6

Példányosítás természetesen

therest · 2012. Jan. 12. (Cs), 12.32
Példányosítás természetesen az include után volt. Köszi a választ, világosabb lett, csak azért fura mert session_start-nál már hozzá nyúl az adatokhoz. Miért nem akkor csinálja az unserialize()-t amikor be akarom állítani, vagyel akarom érni a $_SESSION tömb adott, elemét, hiszen akkor már rendelkezésre áll az osztály.

session_start(); 
include 'cPersons.php'; // itt van az osztálydefiníció
require 'loadUp.php'; // itt kerülnek betöltése a személyek, itt nyúlnék először a session adatokhoz, és itt nyilván értelmezhető már a cPerson osztály
7

Mert a session_start()

MadBence · 2012. Jan. 12. (Cs), 12.46
Mert a session_start() állítja be a $_SESSION tömböt. Ha egy kifejezésben el akarod érni egy elemét, akkor a kiértékelésénél a PHP nem tud valami mágikus callbacket futtatni (ami megint csak valami mágiával kiderítené, mit is szeretnél), mert a $_SESSION is ugyanolyan adatszerkezet, mint bármelyik másik tömb (fixme).
Amit te szeretnél, az a lazy initialization, azaz hogy a PHP ne dolgozzon előre, csak "ha épp szükség van rá". Na ilyet nem tud a beépített munkamenet-kezelő.
8

Kösz a válaszokat! Most is

therest · 2012. Jan. 12. (Cs), 14.27
Kösz a válaszokat! Most is tanultam valami újat.
9

"Nem tudom hogyan tárolja

tgr · 2012. Jan. 14. (Szo), 12.26
"Nem tudom hogyan tárolja szerializáltan az adatokat a php"

Így:
'O:7:"cPerson":2:{s:5:"first";s:5:"Gipsz";s:4:"last";s:5:"Jakab";}'
Egy stdObject-et ebből vissza lehetne állítani, de a láthatóságokat nem tudja kiolvasni belőle, azt meg főleg nem, hogy van-e __wakeup függvény, amit unserialize-kor le kell futtatni.

(Ezeket a c-vel prefixelt osztályneveket egyébként jelölni kéne valami "worst abuse of Hungarian notation" díjra.)
10

Kösz a további

therest · 2012. Jan. 20. (P), 18.56
Kösz a további kiegészítést!

"Ezeket a c-vel prefixelt osztályneveket egyébként jelölni kéne valami "worst abuse of Hungarian notation" díjra."

Soha nem használtam "Hungarian notation"-t, bár már találkoztam vele. Tehát a "c" prefix nem az említett jelölésrendszer helytelen használata (vagy öntrövényű kibővítése), hanem a saját jelölésrendszerem (ami lehet hogy kívülről nem szimpatikus, de nekem megszokott, és kényelmes) része, csak úgy mint az "o" példányosított elemek esetén.
A fentiek ellenére, ha linkelsz valami jelölésrendszert ami szerinted jó, és ami nem típusok, hanem programozási eszközök szerint jelöl, akkor annak örülnék.
11

Nyilván az a fontos, hogy

tgr · 2012. Jan. 29. (V), 14.15
Nyilván az a fontos, hogy neked mi a kényelmes, de én nem tudok elképzelni olyan szituációt, amikor az osztálynév előtti c betűnek bármilyen hasznos információtartalma lenne. PHP-ben a szintaxisból eleve egyértelmű, hogy valami osztály vagy sem (esetleg interfésszel össze lehetne keverni, de abból meg semmilyen hiba nem adódhat).

A magyar jelölésről és annak kisiklásáról egyébként Joelnek van egy jó cikke.