Nesebični statički php str. PHP statičke metode

23. mart 2010 dec5e

PHP 5.3 uveo je zanimljivu funkciju koja se zove kasno statičko vezivanje. Ono što slijedi je malo slobodan prijevod opisa iz službenog priručnika.

Od PHP 5.3.0, jezik je uveo funkciju zvanu kasno statičko vezivanje, koja se može koristiti za referenciranje pozivajuće klase u kontekstu statičkog nasljeđivanja.

Ova karakteristika je nazvana "kasno statičko vezivanje". "Kasno povezivanje" znači da static:: neće biti razriješen u odnosu na klasu u kojoj je metoda definirana, ali će biti procijenjena u vrijeme izvođenja. "Statičko povezivanje" znači da se može koristiti u pozivima statičkim metodama (ali nije ograničeno na njih).

Ograničenja za sebe::

Primjer #1: Upotreba self::

Primjer će ispisati:

Korištenje kasnog statičkog povezivanja

Kasnije statičko povezivanje pokušava riješiti ovo ograničenje uvođenjem ključne riječi koja upućuje na klasu prvobitno pozvanu u vrijeme izvođenja. To jest, ključna riječ koja će omogućiti da se B iz test() referencira u prethodnom primjeru. Odlučeno je da se ne uvodi nova riječ, već da se koristi već rezervirana statička .

Primjer #2: Jednostavna upotreba static::

Primjer će ispisati:

Napomena: static:: ne radi kao $this za statičke metode! $this-> prati pravila nasljeđivanja, ali static:: ne. Ova razlika je pojašnjena u nastavku.

Primjer #3: Upotreba static:: u nestatičnom kontekstu

test(); ?>

Primjer će ispisati:

Napomena: Kasno statičko vezivanje zaustavlja proces rješavanja poziva. Statički pozivi koristeći ključne riječi roditelj:: ili self:: prosljeđuju informacije o pozivu.

Primer #4: Prebacivanje i neprenos poziva

Primjer će ispisati

Edge Cases

Ima ih mnogo na razne načine pozovite metodu u PHP-u, kao što su povratni pozivi ili magične metode. Budući da se kasno statičko vezivanje rješava u vrijeme izvođenja, to može dovesti do neočekivanih rezultata u takozvanim rubnim slučajevima.

Primjer #5 Kasno statičko vezivanje u magijskim metodama

foo; ?>

Reg.ru: domeni i hosting

Najveći registrator i hosting provajder u Rusiji.

Više od 2 miliona imena domena u upotrebi.

Promocija, domenska pošta, poslovna rješenja.

Više od 700 hiljada kupaca širom svijeta već je odlučilo.

*Pređite mišem preko za pauziranje pomicanja.

Nazad napred

Statičke metode i svojstva u PHP-u

U prethodnim materijalima savladali smo osnovne mogućnosti objektno orijentisanog programiranja u PHP-u i sada prelazimo na proučavanje složenijih i zanimljivijih aspekata.

Prije toga smo uvijek radili sa objektima. Klase smo opisali kao šablone koji kreiraju objekte, a objekte kao aktivne komponente čije metode pozivamo i čijim svojstvima pristupamo.

To je dovelo do zaključka da se u objektno orijentiranom programiranju pravi posao obavlja korištenjem instanci klase. A klase su na kraju samo šabloni za kreiranje objekata.

Ali u stvarnosti to nije tako jednostavno. Možemo pristupiti i metodama i svojstvima u kontekstu klase umjesto objekta. Takve metode i svojstva nazivaju se "statičkim" i moraju se deklarirati pomoću ključne riječi statički.

Klasa StaticExample ( statički javni $aNum = 0; statična javna funkcija sayHello() ( ispisati "Zdravo!"; ) )

Statičke metode su funkcije koje se koriste u kontekstu klase. Oni sami ne mogu pristupiti nijednom svojstvu regularne klase, jer takva svojstva pripadaju objektima.

Međutim, među statičkim metodama, kao što ste vjerovatno već pretpostavili, možete pristupiti statičkim svojstvima. A ako promijenite statičko svojstvo, tada će sve instance te klase moći pristupiti novoj vrijednosti.

Budući da se statičkom elementu pristupa kroz klasu, a ne kroz instancu objekta, nije nam potrebna varijabla koja upućuje na objekat. Umjesto toga, koristi se ime klase iza koje slijede dvije dvotočke "::".

Ispis StaticExample::$aNum; StaticExample::sayHello();

Trebalo bi da ste već upoznati sa ovom sintaksom iz osnova OOP-a u PHP-u. Koristili smo konstrukciju "::" u kombinaciji s ključnom riječi roditelj kako bi se pristupilo nadjačanoj metodi roditeljske klase.

Sada, kao i tada, pozivamo se na klasu, a ne na podatke sadržane u objektu. Možete koristiti ključnu riječ u kodu razreda roditelj kako bi se pristupilo superklasi bez korištenja imena klase.

Za pristup statičkoj metodi ili svojstvu iz iste klase (a ne iz podređene klase), koristit ćemo ključnu riječ self.

Ključna riječ self koristi se za pristup trenutnoj klasi i pseudo varijabli $ovo- trenutnom objektu. Stoga izvan razreda StaticExample pristupamo nekretnini $aNum koristeći svoje ime klase.

StaticExample::$aNum;

I unutar razreda StaticExample možete koristiti ključnu riječ self.

Class StaticExample ( static public $aNum = 0; staticka javna funkcija sayHello() ( self::$aNum++; ispis "Zdravo! (" . self::$aNum . ")\n"; ) )

Bilješka: Osim kada se pristupa nadjačanoj metodi roditeljske klase, konstrukciju "::" uvijek treba koristiti samo za pristup statičkim metodama ili svojstvima.

Po definiciji, statičke metode se ne pozivaju u kontekstu objekta. Iz tog razloga, statičke metode i svojstva se često nazivaju varijablama i svojstvima klase. Kao posljedica toga, ne možete koristiti pseudo varijablu $ovo unutar statičke metode.

Zašto uopće koristiti statičku metodu ili svojstvo?

Sada smo došli do najvažnijeg pitanja. Činjenica je da statički elementi imaju niz korisnih karakteristika.

Prvo, dostupni su s bilo kojeg mjesta u skripti (pod uslovom da imate pristup klasi). To znači da možete pristupiti funkcijama bez prosljeđivanja instance klase s jednog objekta na drugi ili, još gore, pohranjivanja instance objekta u globalnu varijablu.

Drugo, statičko svojstvo je dostupno svakoj instanci objekta te klase. Stoga možete definirati vrijednosti koje bi trebale biti dostupne svim objektima date vrste.

I na kraju Treće, sama činjenica da ne morate imati instancu klase da biste pristupili njenom statičkom svojstvu ili metodi izbjeći će stvaranje instanci objekata isključivo radi pozivanja jednostavne funkcije.

Da bismo to demonstrirali, napravimo statičku metodu za klasu ShopProduct koji će automatski instancirati objekte ShopProduct. Definirajmo tablicu koristeći SQLite proizvodi na sljedeći način:

CREATE TABLE proizvoda (ID INTEGER PRIMARNI KLJUČ AUTOINCREMENT, tip TEKST, ime TEKST, glavno ime TEKST, TEKST naslova, cijena float, numpages int, playlength int, popust int)

Sada kreirajmo metodu getInstance(), kojem se prosljeđuje string identifikator i objekt tipa PDO. Oni će se koristiti za preuzimanje reda iz tabele baze podataka, na osnovu koje je objekat tipa ShopProduct, vraćen u program za pozivanje.

Ove metode možemo dodati u klasu ShopProduct, koji je za nas kreiran u ranijim materijalima. Kao što verovatno znate, PDO je skraćenica od PHP Data Object PHP podaci). PDO klasa pruža generički interfejs za različite aplikacije baze podataka.

// Class ShopProduct private $id = 0; javna funkcija setID($id) ( $this->id = $id; ) // ... javna statička funkcija getInstance($id, PDO $pdo) ( $stmt = $pdo->prepare("odaberi * iz proizvoda gdje je id=?"); $rezult = $stmt->izvrši(niz($id)); $red = $stmt->dohvati(); if (prazno($red)) (vrati null; ) if ($ red["type"] == "knjiga") ( $product = novi BookProduct($row["title"], $row["firstname"], $row["mainname"], $row["price"] , $row["numpages"] ) else if ($row["type"] == "cd") ( $product = novi CdProduct($row["title"], $row["firstname"], $row ["mainname"], $row["price"], $row["playlength"] ) ostalo ( $product = new ShopProduct($row["title"], $row["firstname"], $row[" mainname"], $row["price"]); $product->setId($row["id"]); $product->setDiscount($row["discount"]); product; ) // .. .

Kao što vidite, metoda getInstance() vraća objekat tipa ShopProduct, i to je dovoljno „pametno“ na osnovu vrijednosti polja tip kreirati objekat sa potrebnim karakteristikama.

Posebno sam izostavio kod za rukovanje greškama kako bih primjer učinio što sažetijim. Na primjer, u stvarnoj verziji ovog koda koji se izvodi, ne možemo biti previše povjerljivi i pretpostaviti da je proslijeđeni PDO objekt ispravno inicijaliziran i povezan s potrebnom bazom podataka.

U stvari, vjerovatno bismo trebali umotati PDO objekat u klasu koja garantuje ovakvo ponašanje. Vratit ćemo se na ovo pitanje u jednom od naših budućih materijala.

Metoda getInstance() korisniji u kontekstu klase nego u kontekstu objekta. Omogućava nam da lako pretvorimo podatke koji se nalaze u bazi podataka u objekt, a za to ne trebamo imati zasebnu instancu objekta tipa ShopProduct.

Ova metoda ne koristi metode ili svojstva koja zahtijevaju posebnu instancu objekta, tako da nema razloga da se ne proglasi statičnim. Zatim, ako imamo ispravan PDO objekat, možemo pozvati ovu metodu s bilo kojeg mjesta u aplikaciji.

$dsn = "sqlite://home/bob/projects/products.db"; $pdo = novi PDO($dsn, null, null); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $obj = ShopProduct::getInstance(1, $pdo);

Takve metode rade kao "tvornice" u tome što uzimaju "sirove" materijale (na primjer, podatke dobivene iz niza baze podataka ili konfiguracijske datoteke) i koriste ih za kreiranje objekata.

Termin "fabrika" odnosi se na kod koji se koristi za kreiranje instanci objekata. Kasnije ćemo se sastati s vama na primjerima takvih „fabrika“.


Trajne nekretnine

Neka svojstva ne treba mijenjati. Na primjer, elementi kao što su kodovi grešaka ili programski statusni kodovi obično se specificiraju ručno u klasama. Iako bi trebali biti javni i statični, klijentski kod ih ne bi trebao moći mijenjati.

Da biste to učinili, možete definirati trajna svojstva unutar klase. Kao i globalne konstante, konstante klase se ne mogu mijenjati nakon što su definirane. Trajno svojstvo je deklarirano pomoću ključne riječi konst.

Za razliku od običnih nekretnina, nazivu trajnog svojstva ne prethodi znak dolara. Po konvenciji im se često daju imena koja se sastoje od svih velikih slova, kao u sljedećem primjeru:

Klasa ProdavnicaProizvod ( const DOSTUPNO = 0; const VAN_ZALIGE = 1; // ...

Trajna svojstva mogu sadržavati samo vrijednosti koje su specifične za primitivni tip. Konstanti se ne može dodijeliti objekt.

Kao i statička svojstva, trajnim svojstvima se pristupa kroz klasu, a ne kroz instancu objekta. Kao što je konstanta definirana bez znaka dolara, ona također ne zahtijeva nikakav vodeći simbol kada joj pristupa.

Print ShopProizvod::AVAILABLE;

Pokušaj dodjele vrijednosti konstanti nakon što je deklarirana rezultirat će greškom tokom faze raščlanjivanja.

Konstante treba koristiti kada svojstvo mora biti dostupno svim instancama klase i kada vrijednost svojstva mora biti fiksna i nepromjenjiva.

Ovim je ovaj članak završen, a o kojem ćemo govoriti u sljedećem.

Da li vam se dopao materijal i želite da mi se zahvalite?
Samo podijelite sa svojim prijateljima i kolegama!


  • Tutorial

Nije tajna da ljudi vole da postavljaju škakljiva pitanja tokom intervjua. Ne uvijek adekvatno, nije uvijek povezano sa stvarnošću, ali činjenica ostaje činjenica - pitaju se. Naravno, pitanje je drugačije, a ponekad pitanje koje vam se na prvi pogled čini glupim zapravo ima za cilj da provjeri koliko dobro poznajete jezik na kojem pišete.

Pokušajmo jedno od ovih pitanja razdvojiti "komad po dio" - Šta znači riječ “statičan” u PHP-u i zašto se koristi?

Static ključna riječ ima tri različita značenja u PHP-u. Pogledajmo ih hronološkim redom, kako su se pojavili u jeziku.

Prva vrijednost je statička lokalna varijabla

funkcija foo() ( $a = 0; echo $a; $a = $a + 1; ) foo(); // 0 foo(); // 0 foo(); // 0

U PHP-u, varijable su lokalne. To znači da promenljiva definisana i data joj vrednost unutar funkcije (metoda) postoji samo tokom izvršavanja te funkcije (metode). Kada metoda izađe, lokalna varijabla se uništava, a kada ponovo uđe, kreira se iznova. U kodu iznad, takva lokalna varijabla je varijabla $a - ona postoji samo unutar funkcije foo() i kreira se iznova svaki put kada se ova funkcija pozove. Povećanje varijable u ovom kodu je besmisleno, jer će već u sljedećem redu koda funkcija završiti svoj rad i vrijednost varijable će biti izgubljena. Bez obzira koliko puta pozovemo funkciju foo(), ona će uvijek ispisati 0...

Međutim, sve se mijenja ako stavimo ključnu riječ static ispred zadatka:

Funkcija foo() ( statički $a = 0; echo $a; $a = $a + 1; ) foo(); // 0 foo(); // 1 foo(); // 2

Statična ključna riječ, napisana prije dodjeljivanja vrijednosti lokalnoj varijabli, ima sljedeće efekte:

  1. Dodjela se obavlja samo jednom, pri prvom pozivu funkcije
  2. Ovako označena vrijednost varijable se pohranjuje nakon završetka funkcije.
  3. Prilikom narednih poziva funkcije, umjesto dodjeljivanja, varijabla prima prethodno pohranjenu vrijednost
Ova upotreba riječi statički se naziva statička lokalna varijabla.
Podvodne stijene statičke varijable
Naravno, kao i uvijek u PHP-u, postoje neke zamke.

Prvi kamen je da se samo konstante ili konstantni izrazi mogu dodijeliti statičkoj varijabli. Evo koda:
statički $a = bar();
će neizbježno dovesti do greške parsera. Srećom, počevši od verzije 5.6, postalo je moguće dodijeliti ne samo konstante, već i konstantne izraze (na primjer, “1+2” ili “”), odnosno izraze koji ne ovise o drugom kodu i mogu se izračunati u fazi kompilacije

Drugi kamen je da metode postoje u jednoj kopiji.
Ovdje je sve malo komplikovanije. Da biste razumjeli suštinu, evo koda:
klasa A ( javna funkcija foo() ( statički $x = 0; echo ++$x; ) ) $a1 = novo A; $a2 = novo A; $a1->foo(); // 1 $a2->foo(); // 2 $a1->foo(); // 3 $a2->foo(); // 4
Suprotno intuitivnom očekivanju „različiti objekti – različite metode“, u ovom primjeru jasno vidimo da se dinamičke metode u PHP-u „ne množe“. Čak i ako imamo stotinu objekata ove klase, metoda će postojati samo u jednoj instanci, samo će joj se sa svakim pozivom ubacivati ​​različiti $this.

Ovo ponašanje može biti neočekivano za programera koji nije spreman za to i može biti izvor grešaka. Treba napomenuti da nasljeđivanje klasa (i metoda) dovodi do stvaranja nove metode:

Klasa A ( javna funkcija foo() ( statički $x = 0; echo ++$x; ) ) klasa B proširuje A ( ) $a1 = novo A; $b1 = novo B; $a1->foo(); // 1 $b1->foo(); // 1 $a1->foo(); // 2 $b1->foo(); // 2

Zaključak: Dinamičke metode u PHP-u postoje u kontekstu klasa, a ne objekata. I samo u vremenu izvođenja dolazi do zamjene “$this = current_object”.

Drugo značenje su statička svojstva i metode klasa

U PHP objektnom modelu moguće je postaviti svojstva i metode ne samo za objekte - instance klase, već i za klasu u cjelini. Za ovo se također koristi ključna riječ static:

Klasa A ( public static $x = "foo"; javna statička funkcija test() ( return 42; ) ) echo A::$x; // "foo" echo A::test(); // 42
Za pristup takvim svojstvima i metodama koriste se konstrukcije sa dvostrukom dvotočkom (“Paamayim Nekudotayim”), kao što su CLASS_NAME::$Variablename i CLASS_NAME::Methodname().

Podrazumijeva se da statička svojstva i statičke metode imaju svoje karakteristike i zamke koje morate znati.

Prva karakteristika je banalna - nema $ovo. Zapravo, ovo proizilazi iz same definicije statičke metode - budući da je povezana sa klasom, a ne sa objektom, $this pseudo-varijabla, koja ukazuje na trenutni objekat u dinamičkim metodama, nije dostupna. Što je potpuno logično.

Međutim, morate znati da za razliku od drugih jezika, PHP ne detektuje situaciju “$ovo je napisano u statičkoj metodi” u fazi raščlanjivanja ili kompilacije. Ovakva greška može se pojaviti samo u vrijeme izvođenja ako pokušate izvršiti kod s $this unutar statičke metode.

Kod ovako:
klasa A ( public $id = 42; statička javna funkcija foo() ( echo $this->id; ))
neće uzrokovati nikakve greške, sve dok ne pokušate koristiti metodu foo() na neprikladan način:
$a = novo A; $a->foo(); (i odmah dobijete “Fatalna greška: korištenje $this kada nije u kontekstu objekta”)

Druga karakteristika je da statičnost nije aksiom!
klasa A ( statička javna funkcija foo() ( echo 42; ) ) $a = novo A; $a->foo();
To je to, da. Statička metoda, ako ne sadrži $this u kodu, može se pozvati u dinamičkom kontekstu, kao objektna metoda. Ovo nije greška u PHP-u.

Obrnuto nije sasvim tačno:
klasa A ( javna funkcija foo() ( echo 42; ) ) A::foo();
Dinamička metoda koja ne koristi $this može se izvršiti u statičkom kontekstu. Međutim, dobićete upozorenje "Nestatička metoda A::foo() ne treba se zvati statički" na nivou E_STRICT. Na vama je da odlučite hoćete li striktno slijediti standarde koda ili potisnuti upozorenja. Prvi je, naravno, poželjniji.

I usput, sve gore napisano vrijedi samo za metode. Korištenje statičkog svojstva preko "->" je nemoguće i dovodi do fatalne greške.

Treće značenje, koje se čini najteže - kasno statičko vezivanje

Developers PHP jezik se nisu zaustavili na dva značenja ključne riječi “statičan” i u verziji 5.3 dodali su još jednu “karakteristiku” jezika, koja je implementirana istom riječju! To se zove "kasno statično povezivanje" ili LSB (kasno statičko povezivanje).

Najlakši način da shvatite suštinu LSB-a je na jednostavnim primjerima:

Model klase ( public static $table = "table"; javna statička funkcija getTable() (vrat self::$table; ) ) echo Model::getTable(); // "stol"
Ključna riječ self u PHP-u uvijek znači "ime klase u kojoj je ova riječ napisana." U ovom slučaju, self je zamijenjen klasom Model, a self::$table je zamijenjen modelom::$table.
Ova jezička karakteristika se naziva "rano statičko povezivanje". Zašto rano? Zato što se povezivanje self-a i specifičnog imena klase ne događa u vrijeme izvođenja, već u ranijim fazama - raščlanjivanju i kompajliranju koda. Pa, "statična" - jer govorimo o statičkim svojstvima i metodama.

Promenimo malo naš kod:

Model klase (javni statički $table = "tablica"; javna statička funkcija getTable() (vraćanje self::$table; ) ) klasa Korisnik proširuje model (javni statički $table = "users"; ) echo User::getTable() ; // "stol"

Sada razumete zašto se PHP ponaša neintuitivno u ovoj situaciji. self je bio povezan sa klasom Model kada se ništa nije znalo o klasi User, i stoga ukazuje na Model.

Sta da radim?

Da bi se riješila ova dilema, izmišljen je mehanizam "kasnog" povezivanja u fazi izvođenja. Radi vrlo jednostavno - samo napišite "static" umjesto riječi "self" i veza će se uspostaviti s klasom koja poziva ovaj kod, a ne s onom u kojoj je napisan:
class Model ( public static $table = "table"; javna statička funkcija getTable() ( return static::$table; ) ) class Korisnik proširuje model ( public static $table = "users"; ) echo User::getTable() ; // "korisnici"

Ovo je tajanstveno “kasno statičko vezivanje”.

Treba napomenuti da radi veće pogodnosti, u PHP-u, pored riječi “static”, postoji i posebna funkcija get_called_class(), koja će vam reći u kontekstu koje klase vaš kod trenutno radi.

Srećni intervjui!



U svijetu postoje dvije vrste PHP programera. Neki preferiraju statičke metode jer je s njima lako raditi, dok drugi, naprotiv, smatraju statičke metode zlim i ne koriste ih u svojoj praksi.
U ovom članku pokušat ću, koristeći svoje iskustvo u radu s nekoliko okvira, objasniti zašto neki programeri zanemaruju najbolje prakse i koriste čitavu gomilu statičkih metoda.

Ko voli statičke metode?

Posebno ih često koriste programeri koji su ikada koristili CodeIgniter framework u svom radu.

Također, većina Kohana i Laravel programera su sljedbenici statističkih metoda.
Ovdje ne možemo a da ne spomenemo činjenicu da programeri koji odluče da počnu pisati svoje stvari obično odbijaju koristiti CodeIgniter.

Zašto pitate?

CodeIgniter je podržavao PHP 4 pre nego što su statičke metode dodate u PHP 5. Pored toga, CodeIgniter koristi "super objekat" koji daje jednak pristup svim klasama dodeljenim kontroleru. Tako postaju dostupni za upotrebu u cijelom sistemu.

To znači da se klasama može pristupiti iz bilo kojeg modela pomoću metode __get(), koja će potražiti traženo svojstvo koristeći get_instance()->($var). Ranije, kada funkcija __get() nije bila podržana u PHP-u 4, to je urađeno korištenjem foreach konstrukcije kroz parametre CI_Controller i zatim ih dodijeli varijabli $this u modelu.

U biblioteci morate pozvati get_instance. Biblioteka ne forsira nasljeđivanje klasa, tako da ne postoji način da se zaobiđe funkcija __get().

Volumen…

Ovo rezultira prilično glomaznom strukturom za pristup kodu. Potpuno ista funkcionalnost se može postići statičkom metodom bez ikakvog dodatnog napora.

I nema posebne svrhe raspravljati o takvom dizajnu. U redu, možete pristupiti podacima o sesiji u svom modelu. Ali zašto bi ovo uradio?

"rješenje"

Kohana programeri su bili prvi koji su ozbiljno radili na statičkim metodama. Napravili su sljedeće promjene:
//bio je $this->input->get("foo"); // postao Input::get("foo");
Za mnoge CodeIgniter programere sa zastarelim PHP 4 koji su prešli na Kohana framework kako bi iskoristili sve prednosti PHP-a 5, ovo nije ništa neobično. Ali što manje znakova, to bolje, zar ne?

U čemu je problem?

Mnogi PHP programeri (posebno oni koji su dobro upućeni u Symfony i Zend) će reći: „Očigledno je – koristite ubrizgavanje zavisnosti!“ Ali nema mnogo programera u zajednici CodeIgniter koji imaju pravo iskustvo s ovim procesom, jer je prilično složen.

Još jedna činjenica o Fuel PHP framework-u je da do sada uglavnom statičke metode djeluju kao interfejs. Na primjer, logika i dalje ima problema sa statikom, posebno kada je uključen HMVC koncept.

Ovo je pseudokod koji nisam koristio u FuelPHP-u od verzije 1.1:
klasa ControllerA proširuje kontroler (javna funkcija action_foo() (echo Input::get("param");) )
Prilično standardni kod. Ova metoda će dati vrijednost ?bar= u metodi.

Šta se događa kada uputimo HMVC zahtjev ovu metodu?
klasa ControllerB proširuje kontroler ( javna funkcija action_baz() ( echo Input::get("param"); ​​echo " & "; echo Request::forge("controllera/foo?param=val1")->execute() ) )
Pozivanjem u pretraživaču controllerb/baz, vidjet ćete izlaz "val1", ali ako upišete controllerb/baz?param=override, zatim primite oba poziva da dobijete metodu koja vraća istu vrijednost.

Relevantnost

Globalni kod vam neće dati nikakvu relaciju. Primjer je bolji od bilo koje riječi:
$this->request->input->get("param");
Traženi objekt će sadržavati potpuno novu instancu za svaki zahtjev, a zatim će se za svaki zahtjev kreirati ulazni objekt koji sadrži samo ulazne podatke za određeni zahtjev. Ovo važi za FuelPHP 2.0 planove da radi i rešava problem ubrizgavanja zavisnosti kao i probleme sa HMVC.

Šta je sa grubom sintaksom?

Symfony ili Zend programeri ne pate od ovoga, ali oni koji koriste CodeIgniter dugo će imati noćne more o “povratku na PHP 4”.

$this se uvijek odnosi na "trenutni" objekat i definitivno ga ne biste trebali koristiti za pristup globalnom kodu.

$this->request->input->get() može izgledati kao duga forma CodeIgniter sintakse, ali mi smo zapravo samo u kontroleru. Kada kontroler instancira novi upit ugniježđen unutar njega, konstruktor upita također prima instancu kao ulaz.

Ako ste u modelu ili drugoj klasi, pristup poput $this->request->input->foo() neće raditi jer $this nije kontroler.

Input::get("foo") konstrukcija kreira fasadu za logičke instance u pozadini. Ali to ne rješava probleme vezane za rad globalnog koda. Oni koji su najlijeniji prilikom testiranja aplikacija mogu se prebacivati ​​između dva načina rada bez potrebe da u potpunosti koriste novi okvir.

Postoji sjajan video od Taylora Otwella (kreator ili laravel 4) u kojem on opisuje kako možete zamijeniti statički kod s jednom instancom testiranom preko njegovog DiC kontejnera.

Laravel 4 - IoC kontroler Injection & Unit Testing from UserScape on Vimeo.

Ovo je sjajna prezentacija kako se možete izvući ako ne koristite statičke metode u Laravelu. Iako su neki moderni okviri, na prvi pogled, vrlo slični Kohani, oni i najstandardnije probleme rješavaju na potpuno različite načine.

Na ovoj tužnoj noti...

Trenutno sam u procesu pretvaranja PyroCMS-a iz CodeIgniter-a u Laravel. Pokušaj da pređete direktno sa globalnog PHP 4 koda na savršenu injekciju zavisnosti je apsolutno samoubistvo. Srednji korak prije upotrebe CI učitavača je korištenje PHP 5, PSR-2 koda za autoloader sa gomilom statičkih metoda. Pa, za sada smo još uvijek u CodeIgniteru.

Prijelaz sa statičkog na DiC kod može se lako demonstrirati kada konačno napravimo prijelaz na Laravel.

Prelazak sa čvrsto povezanog CodeIgniter koda na PSR-2 koji se može testirati je veliki izazov. Pyro tim je na putu - i to će biti epski.

PHP ima sposobnost da definiše metodu kao statičku. Statička metoda nema pristup svojstvima objekta. Takve metode se mogu pozvati samo u kontekstu klase, a ne u kontekstu objekta.

Najvažnije je razumjeti da statička svojstva i metode pripadaju klasama, a ne objektima.

Primjer će to odmah učiniti jasnim. Kreirajmo objekt Math (skraćeno od matematike na engleskom).

Statički <a href="https://mapstr.ru/bs/php-magicheskie-metody-get-getter-y-i-setter-y-magiya-kotoraya.html">PHP metode</a>
"; $math_1 = nova matematika(); $math_2 = nova matematika(); $math_3 = nova matematika(); $math_4 = nova matematika(); echo "Objekti kreirani: " . Math::getCount(); ?>

Ova klasa pruža alate za rad sa njima matematičke funkcije bez potrebe za kreiranjem objekta. Klasa ima konstruktor koji povećava statičko svojstvo $count za jedan. Klasa pamti vrijednost ovog svojstva jer je statična.

Usput, da biste metodu ili svojstvo proglasili statičkim, koristite riječ static , a da biste pristupili statičkom svojstvu, koristite riječ self praćenu dvostrukom dvotočkom "::".

Sve se to bolje razumije usporedbom, posebno poređenjem radnog primjera s pogrešnim. Proširimo malo naš primjer.

PHP statičke metode counter++; ) javna statička funkcija calcSin($x) ( vrati sin($x); ) javna statička funkcija calcSQRT($x) ( vrati sqrt($x); ) javna statička funkcija getCount() ( vrati self::$count; ) javna funkcija getCounter() (vrati $this->counter; ) ) echo Math::calcSin(1); eho"
"; echo Math::calcSQRT(9); echo "
"; $math_1 = nova matematika(); $math_2 = nova matematika(); $math_3 = nova matematika(); $math_4 = nova matematika(); echo "Objekti kreirani: " . Math::getCount(); echo "
"; echo "Objekti kreirani: " . $math_4->getCounter(); ?>

U ovom primjeru, dodali smo regularno svojstvo $counter klasi, koje je također povećano za jedan u konstruktoru. Ali redovno svojstvo pripada objektu, tako da ne postoji između poziva objekata. Kad god se kreira instanca klase (objekta), svojstvo će biti jednako nuli u konstruktoru će se povećati za jedan.

Statičko svojstvo pripada klasi, tako da je njegova vrijednost očuvana.

Ispod je još nekoliko primjera koji pokazuju kako statička svojstva i metode rade.

Pokušaj korištenja varijable $this u statičkoj metodi rezultirat će greškom (fatalna greška: korištenje $this kada nije u kontekstu objekta).

PHP statičke metode Dob. "staro."; // ovo je greška "Korišćenje $this kada nije u kontekstu objekta". ) ) $TestClass = new TestClass(); $TestClass->sayHello(); ?>

Usput, bez reda:

$TestClass->sayHello();

Neće biti greške, ali čim pokušate da pokrenete statičku metodu sa promenljivom $this u vašem kodu, odmah ćete dobiti poruku o grešci.

Ako uklonite riječ static u ovom primjeru, neće biti greške.

Ako pristupite svojstvu objekta iz statičke metode, to će dovesti do greške. Možete pristupiti samo statičkim svojstvima koristeći self::$age konstrukciju. Imajte na umu da postoji znak $ ispred imena varijable, za razliku od konstrukcije $this->age.

PHP statičke metode reci zdravo(); ?>

U ovom primjeru, ako uklonite riječ static ispred imena svojstva, pojavit će se greška “Pristup nedeklariranom statičkom svojstvu”.

Ne postoje statična svojstva na objektima klase.

PHP statičke metode "; print_r($TestClass); echo ""; ?>

Statička metoda se može pozvati korištenjem self::method() konstrukcije. primjer:

PHP statičke metode printHello(); ?>

Statičko svojstvo se može dobiti u kontekstu klase koristeći sintaksu:

echo TestClass::$age;

Štaviše, pokušaj pristupa redovnom svojstvu na ovaj način dovest će do greške: “Fatalna greška: Pristup nedeklariranom statičkom svojstvu.”

Statičko svojstvo se može promijeniti u kontekstu klase koristeći sintaksu:

TestClass::$age += 20; // Na primjer

Još jedan primjer koda sa statičkim metodama i svojstvima

I u ovom primjeru jednostavne opcije koristeći statičke metode i svojstva. Što jednostavniji kod razumete, bolje ćete zapamtiti materijal.

PHP statičke metode ".TestClass::$age; // echo TestClass::$txt; // Greška: Fatalna greška: Pristup nedeklariranom statičkom svojstvu. echo "
"; TestClass::sayHi(); echo "
"; TestClass::sayHello(); // I ovako sam uspio pristupiti statičkoj varijabli kroz objekat ($obj::$age)... echo "
"; $obj = new TestClass; echo "Pristupanje statičkoj varijabli kroz objekat: " . $obj::$age; ?>

Imajte na umu, i ovo je važno, u ovom primjeru smo pristupili nestatičkoj metodi sayHi() koristeći sintaksu za pristup statičkim članovima klase.

Sažetak

  • Glavna stvar: statička svojstva pripadaju klasama, a ne objektima.
  • Iz statičke metode ne možete pristupiti običnim svojstvima i metodama klase $this->name ovdje ne radi.
  • Iz statičke metode, možete pristupiti statičkim svojstvima koristeći self::$name .
  • Statička svojstva klase nisu dostupna objektima.
  • Normalna metoda može pristupiti statičkom svojstvu koristeći self::$name.
  • Statičko svojstvo se može dobiti u kontekstu klase koristeći sintaksu: TestClass::$age .
  • Redovni metod se može pozvati u kontekstu i objekta ($object->method()) i klase koristeći TestClass::method() sintaksu.
  • Koristeći $object::$age sintaksu, mogao sam pristupiti statičkom svojstvu preko objekta.

Paralele sa JavaScript-om

JavaScript ima klasu Math koja sadrži mnogo različitih matematičkih funkcija.

Da biste izvršili matematička izračunavanja (izračunavanje sinusa ili eksponenta) u JavaScript-u, ne morate kreirati objekat klase Math, jer su njene metode statične. Pre nego što sam naučio PHP, nisam mogao da razumem šta je to, a tek nakon proučavanja klasa i objekata u PHP-u sve mi se složilo na svoje mesto.

Zapravo je vrlo zgodno imati direktan pristup matematičkim metodama klase Math bez potrebe za kreiranjem objekta.

mob_info