ugrás a tartalomhoz

Osztálymetódos meghívása példányosítás nélkül

chop · 2012. Jan. 8. (V), 23.48
Épp a statikus osztálymetódusokról olvasgattam, amikor egy érdekes dolgot vettem észre:

class Foo {
	public static function bar() {
		print 'Egy bar vagyok.';
	}
}

print Foo::bar();
Itt ugye szépen kiírja a várt szöveget, ami rendben is van: statikus tagfüggvénynél működik a példányosítás nélküli függvényhívás.

Azonban ha kihagyom a static kulcsszót a függvény meghatározásából, akkor is meg lehet azt hívni objektumpéldány nélkül. Tehát kvázi direktben lehet hívni egy osztálymetódust (amelyik persze public vagy protected), anélkül, hogy mondjuk a konstruktor is automatikusan lefutna.

class Foo {
	public function __construct() {
		throw new Exception('Itt le kéne állni!');
	}
	
	public function bar() {
		print 'Egy bar vagyok.';
	}
}

//$foo = new Foo();

print Foo::bar();
Csak nekem fura ez a viselkedés?:)
 
1

Kompatibilitas

szeber · 2012. Jan. 9. (H), 00.00
Ennek a viselkedesnek az az oka, hogy PHP 4-ben nem letezett static kulcsszo, es minden osztalyfuggveny hivhato volt statikusan, maximum $this hasznalatakor kaptal fatal errort, vagy meglepo viselkedest.
PHP 5 eseten ha a script hibak be vannak kapcsolva, akkor egy nem statikusnak deklaralt metodus statikus hivasa eseten E_SCRIPT hibat fogsz kapni, de ettol fuggetlenul mukodni fog. Persze a staikusan hivott metodusban torteni $this hasznalat tovabbra is fatal errort vagy erdekes viselkedest fog eredmenyezni.
5

E_STRICT, nem

Tyrael · 2012. Jan. 9. (H), 17.24
E_STRICT, nem E_SCRIPT

Tyrael
26

Hubasszus, ennyire faradt

szeber · 2012. Jan. 11. (Sze), 19.22
Hubasszus, ennyire faradt voltam mar? :) Sorry, igen E_STRICT , es a hibak se script, hanem strict-nek indultak.
27

Azért volt nekem gyanús,

inf · 2012. Jan. 11. (Sze), 21.34
Azért volt nekem gyanús, mondom erről a script típusú hibáról még nem hallottam, dehát biztos jól tudod :D
2

előttem már megválaszolták a

Kubi · 2012. Jan. 9. (H), 15.41
előttem már megválaszolták a kérdésed, csak annyit tennék hozzá, print helyet echo-t használj, echo gyorsabb és egy karakterrel rövidebb :)
3

echo gyorsabb Mikor mérted

kuka · 2012. Jan. 9. (H), 16.11
  • echo gyorsabb
    Mikor mérted utoljára? Mert PHP 5.3.8-an én nem találtam egyértelmű eltérést 10 000 000 echo és print között.
  • egy karakterrel rövidebb :)
    Ennél jobb érv az, hogy echo több paramétert is elfogad, ezért megspórolhatsz néhány fölösleges karakterlánc összeillesztést.
4

my 2 cents: echo nyelvi

Tyrael · 2012. Jan. 9. (H), 17.06
my 2 cents:
echo nyelvi konstrukcio, nem fuggveny, emiatt valoban gyorsabb egy hangyanyit:
http://codepad.viper-7.com/Vp0bLC 3 opcode
vs
http://codepad.viper-7.com/gMY1Lw 2 opcode

a masik kovetkezmenye ennek, hogy az echo-nak nincs visszateresi erteke (pontosabban nem hasznalhato olyan kornyezetben).

azt hiszem mindent elmondtunk rola, amit tudni lehet. :)

Tyrael
6

A print se függvény

pp · 2012. Jan. 9. (H), 17.45
http://hu.php.net/print

Az echo-nak nincs visszatérési értéke a print-nek meg van. Ebből adódik a különbség.
7

/o\ es tenyleg,

Tyrael · 2012. Jan. 9. (H), 17.54
/o\ es tenyleg

a gyakorlatban a ZEND_PRINT is a ZEND_ECHO-t hajtja vegre, csak a beallitja a visszateresi erteket konstans 1-re, es visszater vele:
http://lxr.php.net/opengrok/xref/PHP_TRUNK/Zend/zend_vm_def.h#973

Tyrael
8

Az előbb, igaz egy virtuális

H.Z. v2 · 2012. Jan. 9. (H), 18.19
Az előbb, igaz egy virtuális gépben, kipróbáltam, hogy százmillió "." karaktert kiküldtem a stdout-ra, amit a /dev/null-ba irányítottam.

for($i=0;$i<99999999;$i++)print ".";
Nyolc-tíz alkalommal futtattam a print-es és az echo-s változatot. Kb. 35-40mp alatt futott le mindkettő, hibahatáron belüli eltérésekkel.
Szóval én nem láttam érzékelhető különbséget a két parancs sebességében.
(ubuntu 10.04 default telepítés, nem tudom mennyire van optimalizálva a php-je. Nem lennék meglepve, ha kiderülne, hogy miután nem használom a visszatérési értéket, egyszerűen az optimalizáló echo-t tesz a print helyére)
9

Szerintem korábban a print

Hidvégi Gábor · 2012. Jan. 9. (H), 18.58
Szerintem korábban a print máshogy működött, mert én is abban a hitben voltam, mint te. Sőt, úgy emlékeztem, hogy azért volt visszatérési értéke, mert ellenőrizte, hogy sikeres volt-e a kiírás.
10

én is úgy tudtam, hogy

Kubi · 2012. Jan. 9. (H), 20.47
én is úgy tudtam, hogy gyorsabb, mindenesetre így is maradok az inkább echo mint print véleményemnél, print-et nem is látok manapság egy leíársban, kódban sem.
12

"Szép" sorozat!

Pepita · 2012. Jan. 10. (K), 09.25
Csupa-csupa off. "Köszönöm" a kérdező nevében.
11

Akkor már vegyük bele

inf · 2012. Jan. 10. (K), 00.17
Akkor már vegyük bele a
file_put_contents('php://output', "Hello, World!");
Ez 4 opcode. :-)

Egyébként nem értem, hogy ennek az egésznek mi a jelentősége, én egyszer szoktam kimenetre tolni adatot: ha elküldöm a választ a kliensnek...
13

Nekem furcsa

Pepita · 2012. Jan. 10. (K), 09.28
Kérdésedre már válaszoltak, én viszont nem értem, hogy miért print Foo::bar();-al hívod a függvényt. Nem kell a print, mivel a fv-ben ott van. Csak Foo::bar();.
22

Először is köszönöm a

chop · 2012. Jan. 10. (K), 22.24
Először is köszönöm a választ, így már érthető a dolog.

Másrészt az észrevétel jogos, a válasz pedig a figyelmetlenség.
14

Nem értem, hogy mi vezetett

inf · 2012. Jan. 10. (K), 11.26
Nem értem, hogy mi vezetett oda, hogy így próbálsz metódust hívni, de sürgősen felejtsd el. Sőt ha megteheted akkor a statikus metódusokat is, helyette használj inkább singletont.
15

"akkor a statikus metódusokat

Tyrael · 2012. Jan. 10. (K), 15.11
"akkor a statikus metódusokat is, helyette használj inkább singletont."
uhm, what?
marmint aki ellenjavalja a statikus metodusokat, az altalaban a Singleton pattern it, hiszen a getInstance() ott is egy statikus metodus.

es ugye a statikus metodusokat a global state es az implicit dependencia miatt nem szeretjuk, az ilyen kodot nehezebb tesztelni (reszletekert lasd ezt illetve ezt )

Tyrael
16

marmint aki ellenjavalja a

inf · 2012. Jan. 10. (K), 15.29
marmint aki ellenjavalja a statikus metodusokat, az altalaban a Singleton pattern it, hiszen a getInstance() ott is egy statikus metodus.


Jóva, nem kell szőrszálhasogatni :D (Egyébként gondoltam, hogy beleírom, hogy az Instance metódust leszámítva, de szerintem így is érthető a cél, ha valaki tisztában van azzal a mintával ...)

Nekem sajna nem sikerült megúszni a php-t singleton nélkül. (Mondjuk csak egy helyen használom, a többinél sikerült elkerülni kis utánagondolással.)
17

tradeoff, szerintem van olyan

Tyrael · 2012. Jan. 10. (K), 16.28
tradeoff, szerintem van olyan szituacio, ahol megeri hasznalni, tobbet nyersz a kenyelemmel, mint amit veszitesz a huzalozassal es a nehezebb tesztelhetoseggel.
ettol fuggetlenul a jelenlegi trendek azt mutatjak, hogy a PHP frameworkokben is mindenki igyekszik a DI/DIC fele mozogni, pl. anno a Symfony is tele volt Singleton-okkal, de a Symfony2-be mar mindenutt DIC-t hasznalnak, amennyire tudom, Zend Framework detto, 2-es verzioban ok is DIC-re tertek at, es a Singleton-okat lekukaztak.

ps: nyilvan egy framework eseteben sokkal fontosabb, hogy rugalmas es jol tesztelheto legyen, szoval itt nagyobb haszna is van a DI-nek, de az alkalmazas fejlesztok is kovetni fogjak a trendeket.

Tyrael
18

Mit jelent?

H.Z. v2 · 2012. Jan. 10. (K), 18.55
A DIC-ből a C mit takar? (A Dependency Injectionig eljutottam)
19

dependency injection

inf · 2012. Jan. 10. (K), 20.58
dependency injection container ha jól tudom
20

arra gondoltam, igen. Tyrael

Tyrael · 2012. Jan. 10. (K), 21.38
arra gondoltam, igen.

Tyrael
21

Köszi

H.Z. v2 · 2012. Jan. 10. (K), 21.49
Köszi
23

Hogy érted azt, hogy "így"?

chop · 2012. Jan. 10. (K), 22.30
Hogy érted azt, hogy "így"? Ha úgy érted, hogy példányosítás nélkül, közvetlenül osztályból, akkor láthatod, hogy ez demonstratív példa volt, ami nem jelenti azt, hogy máskor is így használom. A topik kérdése pontosan az volt, hogy miért lehet példányosítás nélkül is metódust meghívni? Ha létrehozok egy objektumot és úgy hívom meg a metódust, akkor hogy mutatom be a példányosítás nélküli metódushívást?...:)

A legelső PHP-könyvemben (kb. 7 éve, azóta kihagytam vagy 4 évet) a szerző a printet használta, nekem meg ez maradt meg. De lehet, hogy az echo valóban jobb.
24

Hogy érted azt, hogy "így"?

inf · 2012. Jan. 10. (K), 22.54
Hogy érted azt, hogy "így"? Ha úgy érted, hogy példányosítás nélkül, közvetlenül osztályból, akkor láthatod, hogy ez demonstratív példa volt, ami nem jelenti azt, hogy máskor is így használom. A topik kérdése pontosan az volt, hogy miért lehet példányosítás nélkül is metódust meghívni?

Hát passz, nekem mondjuk az furcsa, hogy a parent::method is ugyanígy kettőspontokkal működik...

A legelső PHP-könyvemben (kb. 7 éve, azóta kihagytam vagy 4 évet) a szerző a printet használta, nekem meg ez maradt meg. De lehet, hogy az echo valóban jobb.

Teljesen mindegy melyiket használod, garantálom, hogy soha az életben nem lesz érezhető különbség a kettő között...

Mondjuk megintcsak érdekes, hogy 3 féleképpen lehet kimenetre adatot küldeni. Én fix, hogy csak az egyiket hagytam volna meg ezek közül. (Nekem az output stream-re mentés a szimpatikus egyébként.)
25

[qoute]Hát passz, nekem

chop · 2012. Jan. 10. (K), 23.08
Hát passz, nekem mondjuk az furcsa, hogy a parent::method is ugyanígy kettőspontokkal működik...


Nalátod!:)