Contacte

Membrii de clasă statică. Nu le dați să vă ruineze codul. Metode PHP statice Primel Static PHP P

Nu este un secret că vă place să întrebați întrebări complicate cu privire la interviuri. Nu întotdeauna adecvați, nu întotdeauna legați de realitate, dar faptul rămâne un fapt - întreabă. Desigur, întrebarea este o problemă și, uneori, întrebarea, la prima vedere, aparent proastă, este de fapt îndreptată să verifice cât de bine știi limba pe care o scrieți.

Să încercăm să dezasamblați una dintre aceste întrebări " ce înseamnă cuvântul "static" în PHP și de ce se aplică?

Cuvântul cheie Static are trei valori diferite în PHP. Îi vom analiza în ordine cronologică, așa cum au apărut în limba.

Prima valoare este o variabilă locală statică

Funcție foo () ($ a \u003d 0, echo $ a; $ a \u003d $ a + 1;) foo (); // 0 foo (); // 0 foo (); // 0.

În variabilele PHP locale. Aceasta înseamnă că variabila definită și valoarea din interiorul funcției (metoda) există numai în timpul executării acestei funcții (metodă). Când părăsiți metoda, variabila locală este distrusă și când reintroducerea, se desfășoară. În codul de mai sus o astfel de variabilă locală este o variabilă $ - există numai în interiorul funcției Foo () și de fiecare dată când apelați această funcție este interzisă. Creșterea variabilei în acest cod este lipsită de sens, deoarece pe următoarea linie a codului, funcția va termina funcționarea și valoarea variabilei va fi pierdută. De câte ori nu am făcut funcția foo (), va lua întotdeauna 0 ...

Cu toate acestea, totul se schimbă, dacă punem cuvântul cheie static înainte de alocare:

Funcție foo () (static $ a \u003d 0; echo $ a; $ a \u003d $ a + 1;) foo (); // 0 foo (); // 1 foo (); // 2.

Cuvântul cheie static scris înainte de alocarea valorii variabilei locale duce la următoarele efecte:

  1. Alocarea este efectuată o singură dată, când introduceți mai întâi funcția
  2. Valoarea marcată în acest mod variabila este salvată după finalizarea operației.
  3. Cu apelurile funcției ulterioare, în loc de atribuire, variabila primește valoarea salvată anterior
O astfel de utilizare a cuvântului static este numită variabila locală statică.
Variabila statică subacvatică
Desigur, ca întotdeauna în PHP, nu costă fără "capcane".

Piatra este prima variabilă statică pentru a atribui numai constantelor sau expresiilor constante. Iată codul:
Static $ a \u003d bar ();
Cu inevitabilitatea va duce la o eroare parser. Din fericire, începând cu versiunea 5.6, a devenit admisibilă pentru alocarea nu numai a constantelor, ci și expresii constante (de exemplu - "1 + 2" sau ""), adică astfel de expresii care nu depind de celălalt cod și pot fi calculată la etapa de compilare

Metodele de piatră secundă există într-o singură copie.
Totul este mai complicat aici. Pentru a înțelege esența, voi da codul:
Clasa A (Funcția Publică Foo () (static $ x \u003d 0; Echo ++ $ x;)) $ A1 \u003d New A; $ a2 \u003d New A; $ a1-\u003e foo (); // 1 $ A2-\u003e Foo (); // 2 $ A1-\u003e Foo (); // 3 $ A2-\u003e Foo (); // patru.
Contrar așteptărilor intuitive pentru "obiecte diferite - diferite metode", vedem vizual acest exemplu că metodele dinamice în PHP "nu se înmulțesc". Chiar dacă avem o sută de obiecte din această clasă, metoda va exista doar într-o singură instanță, doar cu fiecare apel la acesta va fi înmuiați diferit de acest lucru.

Un astfel de comportament poate fi neașteptat pentru dezvoltatorul nepregătit pentru el și să servească drept sursă de erori. Trebuie remarcat faptul că moștenirea clasei (și a metodei) duce la faptul că este creată o nouă metodă:

Clasa A (Funcția Publică Foo () (static $ x \u003d 0; echo ++ $ x;)) Clasa B extinde a () $ A1 \u003d nou A; $ b1 \u003d nou b; $ a1-\u003e foo (); // 1 $ b1-\u003e foo (); // 1 $ A1-\u003e Foo (); // 2 $ b1-\u003e foo (); // 2.

Concluzie: Există metode dinamice în PHP în contextul clasei, nu obiecte. Și numai în clasament există o substituție "$ acest \u003d actual_object"

Adică proprietăți statice și metode de clasă

În modelul obiectului PHP, este posibilă setarea proprietăților și a metodelor nu numai pentru instanțele de clasă a obiectelor, ci și pentru o clasă în ansamblu. Pentru a face acest lucru, servește și cuvântul cheie static:

Clasa A (static public $ x \u003d "foo", testul de funcții statice publice () (return 42;)) Echo A: $ x; // "foo" Echo A :: Test (); // 42.
Pentru accesul la astfel de proprietăți și metode, sunt utilizate structuri cu un colon dublu ("PAAMAYIM Nekudotayim"), cum ar fi numele_name :: $ scop și name_name :: Namemode ().

Este de la sine înțeles că proprietățile statice și metodele statice au caracteristicile proprii și "capcanele lor" pe care trebuie să le cunoașteți.

Caracteristica este primul, banal - nu $ acest lucru. De fapt, acest lucru provine din foarte mult de definiția metodei statice - deoarece este asociată cu clasa, și nu un obiect, nu este disponibil pentru Pseudo-Temperatură $ acest lucru, indicând în metodele dinamice la obiectul curent. Ceea ce este complet logic.

Cu toate acestea, trebuie să știți că, spre deosebire de alte limbi, PHP nu definește situația "în metoda statică este scrisă acest lucru" în stadiul de parsare sau compilație. O eroare similară poate apărea numai în ratarul dacă încercați să efectuați codul cu $ în interiorul metodei statice.

Codul de tip Astfel:
Clasa A (Public $ id \u003d 42; Funcția publică statică Foo () (ECHO $ \u200b\u200bAcest- id;))
Nu va duce la erori, atâta timp cât nu încercați să utilizați metoda Foo () în mod necorespunzător:
$ a \u003d nou A; $ a-\u003e foo (); (și obțineți imediat "eroare fatală: folosind acest lucru atunci când nu în contextul obiectului")

Caracteristică două - static nu este o axioma!
Clasa A (funcția publică statică Foo () (ECHO 42;)) $ a \u003d nou A; $ a-\u003e foo ();
Ca asta, da. Metoda statică, dacă nu conține codul $ acest lucru, este posibil să apelați într-un context dinamic ca metodă de obiect. Aceasta nu este o eroare în PHP.

Reversul nu este adevărat:
Clasa A (Funcția Publică Foo () (ECHO 42;) A :: Foo ();
O metodă dinamică care nu utilizează $ acest lucru poate fi efectuată într-un context static. Cu toate acestea, veți primi un avertisment "Metoda non-statică A :: Foo () nu trebuie să fie numită static" E_STRGT nivel. Acolo pentru a vă rezolva - sau respectați cu strictețe standardele de cod sau suprimați avertismentele. Primul, desigur, este preferabil.

Și apropo, totul scris mai sus se aplică numai la metode. Utilizarea proprietăților statice prin "-\u003e" este imposibilă și duce la o eroare fatală.

Valoarea este a treia, aparentă cea mai dificilă - mai târziu legată statică

Dezvoltatorii limbajului PHP nu s-au oprit la cele două valori ale cuvântului cheie "static" și în versiunea 5.3 a adăugat o altă limbă "caracteristică", care este implementată de același cuvânt! Se numește "legarea statică mai târziu" sau LSB (legarea statică târzie).

Înțelegeți esența LSB este cea mai ușoară modalitate de a fi simple exemple:

Modelul de clasă (Public Static $ Tabel \u003d "Tabel"; Funcția publică statică Gettable () (Return Self: $;)) Echo Model :: Gettable (); // "Masa"
Cuvântul cheie de sine în PHP înseamnă întotdeauna "nume de clasă, unde este scris acest cuvânt". În acest caz, sinele este înlocuit de clasa modelului și de sine :: $ Tabel - pe model :: $ Tabel.
O astfel de posibilitate de limbă se numește "legare statică timpurie". De ce devreme? Deoarece legarea de sine și numele specific al clasei nu se găsesc în Ranktime, dar la etapele anterioare - parsarea și compilarea codului. Ei bine, "static" - pentru că vorbim despre proprietăți și metode statice.

Modificați ușor codul nostru:

Model de clasă (Public Static $ Tabel \u003d "Tabel"; Funcția publică statică Gettable () (returnare auto :: $ tabelă;)) Clasa utilizator extinde modelul (public static $ tone \u003d "utilizatori";) Echo utilizator :: gettable () ; // "Masa"

Acum înțelegeți de ce PHP se comportă în această situație nonintuitiv. Sinele a fost asociat cu clasa modelului când clasa de utilizator nu a fost încă cunoscută, prin urmare indică modelul.

Cum să fii?

Pentru a rezolva această dilemă, mecanismul de legare "târziu" a fost inventat, în stadiul Ranktime. Funcționează foarte simplu - suficient în loc de cuvântul "sine" scrie "static", iar conexiunea va fi instalată cu clasa care provoacă acest cod și nu cu unde este scris:
Model de clasă (Public Static $ Tabel \u003d "tabel"; Funcția publică statică gettable () (return static :: $ tabelă;))), utilizatorul de clasă extinde modelul (static public $ Tabel \u003d "utilizatori";) Echo utilizator :: gettable () ; // "Utilizatori"

Aceasta este o misterioasă "mai târziu legată statică".

Trebuie remarcat faptul că pentru o mai mare comoditate în PHP, cu excepția cuvântului "static", există încă o funcție specială get_called_class (), care vă va informa - în contextul căruia clasa este în prezent codul dvs. de cod.

Interviuri de succes!



Există două soiuri de dezvoltatori PHP din lume. Unele preferă metode statice, deoarece este ușor de lucrat cu ei, alții, în contrast, ia în considerare metodele statice - răul și nu le folosesc în practica lor.
În acest articol voi încerca să folosesc experiența cu mai multe cadre, să explicăm de ce unii dezvoltatori ignoră cele mai bune practici și să utilizeze o grămadă de metode statice.

Cine iubește metodele statice?

Mai ales adesea folosesc dezvoltatorii care au folosit vreodată în codeignia de cadru de lucru.

De asemenea, urmașii metodelor statistice includ majoritatea dezvoltatorilor Kohana și Laravel.
Este imposibil să nu mai vorbim de faptul că programatorii care decid să înceapă să-și scrie propriile lucruri, de obicei, refuză să folosească codeignire.

De ce întrebați?

CodeGenter acceptat PHP 4 Înainte de adăugarea metodelor statice la PHP 5. În plus, CodeGenterul utilizează un "super obiect", care oferă acces egal la toate clasele atribuite controlerului. Astfel, acestea devin accesibile pentru utilizare pe tot parcursul întregului sistem.

Aceasta înseamnă că clasele pot fi disponibile din orice model utilizând metoda __get (), care va căuta proprietatea solicitată utilizând get_insance () -\u003e ($ var). Anterior, când suportul pentru funcția __get () nu a fost în PHP 4, pentru că acest lucru a fost utilizat proiectul de predare prin parametrii CI_controller și apoi au fost alocate acestei variabile de $ în model.

În biblioteca trebuie să apelați Get_insance. Biblioteca nu moștenește o clasă într-o ordine obligatorie, deci nu există nici o modalitate de a ocoli funcția __get ().

Volum ...

Se pare că un design destul de greoaie pentru a accesa codul. Exact aceeași funcționalitate fără eforturi suplimentare pot fi realizate utilizând o metodă statică.

Da, și nu există nici un sens special de a argumenta despre un astfel de design. Ei bine, puteți accesa datele sesiunii din modelul dvs. Dar de ce trebuie să faci asta?

"Decizie"

Dezvoltatorii din Kohana au fost primii care au lucrat serios peste metode statice. Au făcut următoarele modificări:
// a fost $ acest-\u003e intrare-\u003e obține ("foo"); // a devenit intrare :: obține ("foo");
Pentru mulți dezvoltatori de codeignire cu PHP-ul lor depășit PHP 4, care s-au mutat la cadrul Kohana pentru a beneficia de toate PHP 5 farmece, nu este nimic neobișnuit în acest sens. Dar, cu atât mai puține personaje, cu atât mai bine, nu?

Și care este problema?

Mulți dezvoltatori PHP (în special cei care înțeleg Symfony și Zend) vor spune: "Este evident - folosiți introducerea dependențelor!" Dar nu mulți dezvoltatori din comunitatea Codeignitelor au o experiență reală cu acest proces, deoarece este destul de complicată.

Un alt fapt despre cadrul de combustibil PHP este în continuare în principal metode statice acționează ca o interfață. De exemplu, logica are încă probleme cu static, mai ales când conceptul HMVC este activat.

Acesta este un pseudocod pe care nu l-am folosit în FIELFP, începând cu versiunea 1.1:
Class Controllera se extinde controlerul (Funcția Publică Action_Foo (Input Echo :: Obțineți ("Param");))
Cod destul de standard. Această metodă va emite valoarea ? Bar \u003d. în metodă.

Ce se întâmplă când facem o cerere HMVC la această metodă?
Class ControllerB se extinde controlerul (Echo Input :: Get ("Param"), Echo "&" Echo Solicitare :: Forge (Controllera / Foo PARAM \u003d VAL1 ") -\u003e Execute ();))
Apelarea în browser controllerb / Baz.Veți vedea ieșirea "Val1", dar dacă veți obține controllerb / Baz? Param \u003d OverrideVeți primi ambele provocări pentru a obține metoda care returnează aceeași valoare.

Relevanţă

Codul global nu vă va oferi nici o relație. Un exemplu este mai bun decât orice cuvinte:
$ this-\u003e solicitare-\u003e intrare-\u003e obține ("param");
Obiectul solicitat va conține o instanță complet nouă pentru fiecare interogare, apoi introducerea obiectului va fi creată pentru fiecare cerere, care conține numai date de intrare pentru o interogare specifică. Acest lucru este valabil pentru FIELPHP 2.0 planurile de a lucra și rezolvă problema adăugării dependenței, precum și a problemelor cu HMVC.

Cum de a face față sintaxei brute?

Dezvoltatorii Symfony- sau Zend nu suferă atât de mult, dar cei care folosesc codeignire vor fi mult timp coșmaruri despre "întoarcerea la PHP 4".

$ Acest lucru se referă întotdeauna la obiectul "curent" și nu este necesar să îl utilizați pentru a accesa codul global.

$ this-\u003e solicitare-\u003e intrare-\u003e obține () poate arata ca o formă de codignire alungită, dar de fapt suntem pur și simplu în controler. Când controlerul creează o instanță a noii interogări introduse în acesta, constructorul de interogare primește, de asemenea, o instanță la intrare.

Dacă vă aflați într-un model sau altă clasă, atunci accesul este tipul de $ Acest-\u003e Solicitare-\u003e Input-\u003e Foo () nu va funcționa, deoarece $ nu este controlerul.

Intrare :: Obțineți design ("foo") creează o fațadă pentru instanțe logice în fundal. Dar acest lucru nu rezolvă probleme legate de activitatea codului global. Leneșul când aplicațiile de testare pot comuta între două moduri fără a fi nevoie să utilizați pe deplin noul cadru.

Există un videoclip excelent de la Taylor Oblla (Creator sau Laravel 4) în care descrie modul în care puteți înlocui codul static cu o singură instanță verificată prin containerul său DIC.

Laravel 4 - Injectarea controlerului IOC și testarea unității de la UserScape pe Vimeo.

Aceasta este o prezentare excelentă a modului în care puteți face fără utilizarea metodelor statice în Laravel. Deși unele cadre moderne, la prima vedere, sunt foarte amintite de Kohana, ei rezolvă absolut chiar și cele mai standard sarcini în moduri diferite.

Pe această notă tristă ...

Acum sunt angajat în conversia PyrocMs cu CodeGenter pe Laravel. Încerc să mă mișc direct de la codul global PHP 4 la implementarea perfectă a dependențelor este o sinucidere absolută. Pasul intermediar înainte de a utiliza bootloaderul CI - Utilizarea codului PHP 5, codul PSR-2 încărcat automat cu o grămadă de metode statice. Ei bine, în timp ce suntem încă în codeignire.

Trecerea de la statica la codul DIC poate fi ușor demonstrată atunci când facem în sfârșit tranziția spre Laravel.

Tranziția de la codul de codegnitru al subliniului la PSR-2 testat este sarcina principală. Echipa Pyro este deja pe drum - și va fi epică.

În PHP, este posibil să se determine metoda ca statică. Metoda statică nu are acces la proprietățile obiectului. Astfel de metode pot fi cauzate numai în contextul clasei, dar nu în contextul obiectului.

Cel mai important lucru este înțelegerea - proprietățile și metodele statice sunt prezentate de clase, nu de obiecte.

Exemplul va deveni imediat clar. Să creăm un obiect matematic (abreviat de matematică în limba engleză).

Metode statice PHP.
"$ Math_1 \u003d Noua matematică (); $ Math_2 \u003d Noua matematică (); $ Math_3 \u003d Noua matematică (); $ Math_4 \u003d Noua matematică (); echo" obiecte create: "Math :: Getcount ();?\u003e

Această clasă oferă instrumente pentru a lucra cu funcții matematice fără a fi nevoie să creați un obiect. Clasa are un constructor care mărește proprietatea statică a numărului de dolari pe unitate. Clasa își amintește valoarea acestei proprietăți, deoarece este statică.

Apropo, cuvântul cuvânt static este folosit pentru a decla metoda sau proprietatea statică, iar cuvântul de sine cu un colon dublu este folosit pentru a accesa o proprietate statică "::".

Toate acestea sunt cele mai bine înțelese în comparație, în special în compararea exemplului de lucru cu eronat. Să ne extindem ușor exemplul.

Metode statice PHP. counter ++; ) Funcția statică publică Calcsină ($ x) (returnați păcatul ($ x);) Funcția statică publică CalcsQRT ($ x) (return SQRT ($ x);) Funcția statică publică Getcount (Return Self :: $ numărul;) Funcția publică GetCounter () (Return $ acest-\u003e contor;)) Echo matematică :: Calcizina (1); Echo "
"Echo Math :: Calcsqrt (9); Echo"
"$ Math_1 \u003d noua matematică (); $ Math_2 \u003d nou matematică (); $ Math_3 \u003d nou matematică (); $ mateth_4 \u003d noua matematică (); echo" obiecte create: "Math :: Getcount (); Echo"
"Echo" obiecte create: "$ mateth_4-\u003e getcounter ();?\u003e

În acest exemplu, am adăugat clasa proprietății obișnuite de $, a crescut, de asemenea, cu unul în constructor. Dar proprietatea obișnuită aparține obiectului, deci nu este salvată între provocările obiectelor. Cu orice creare a unei instanțe a unei clase (obiect), proprietatea va fi egală cu Nulo, în designer va fi majorat cu unul.

Proprietatea statică aparține clasei, astfel încât valoarea sa este salvată.

Mai jos sunt câteva exemple care dezvăluie activitatea proprietăților și metodelor statice.

Încercarea de a utiliza în metoda statică $ Această variabilă va duce la eroare (eroare fatală: folosind acest lucru atunci când nu în contextul obiect).

Metode statice PHP. vârstă. "VECHI."; // Aceasta este o eroare "folosind $ acest lucru atunci când nu în contextul obiect". )) $ TestClass \u003d TestClass nou (); $ TestClass-\u003e Sayhello (); ?\u003e.

Apropo, fără un șir:

$ TestClass-\u003e Sayhello ();

erorile nu vor fi, dar de îndată ce încercați să începeți metoda statică din această variabilă $, primiți imediat un mesaj de eroare.

Dacă în acest exemplu, eliminați cuvântul static, atunci erorile nu vor fi.

Dacă vă referiți la proprietatea obiectului din metoda statică, aceasta va duce la o eroare. Puteți aplica numai proprietățile statice utilizând designul de sine :: $ AGE Design. Vă rugăm să rețineți că există un semn de $ în fața numelui variabil, spre deosebire de designul de vârstă.

Metode statice PHP. spune buna (); ?\u003e.

Dacă în acest exemplu, eliminați cuvântul static în fața numelui de proprietate, atunci va apărea eroarea "Acces la Proprietatea Statică nedeclarată".

Proprietățile statice sunt absente în obiectele de clasă.

Metode statice PHP. ", Imprimare_r ($ testclass); echo""; ?>

Metoda statică poate fi numită folosind metoda Self :: metoda (). Exemplu:

Metode statice PHP. printhello (); ?\u003e.

Proprietatea statică poate fi obținută în contextul clasei utilizând sintaxa:

echo TestClass :: $ vârsta;

Mai mult, o încercare de a se referi la proprietatea obișnuită va duce astfel la o eroare: "Eroare fatală: acces la proprietatea statică nedeclarată".

Proprietatea statică poate fi modificată în contextul clasei utilizând sintaxa:

TestClass :: $ Vârsta + \u003d 20; // de exemplu

Un alt exemplu de cod cu metode și proprietăți statice

În acest exemplu, mai multe opțiuni simple pentru utilizarea metodelor și proprietăților statice. Codul mai simplu pe care îl veți înțelege, cu atât mai bine să vă amintiți materialul.

Metode statice PHP. ".Testclass :: $ Vârstă; // TestClass :: $ txt; // eroare: eroare fatală: acces la proprietate statică nedeclarată. Echo"
", TestClass :: Sayhi (); echo"
"TestClass :: Sayhello (); // și așa că aș putea avea acces la o variabilă statică prin obiect ($ obj :: $ vârsta) ... eco"
"$ obj \u003d New TestClass; Echo" Obținem o diplomă la o variabilă statică prin obiect: "$ obj :: $ vârsta;?

Notă, iar acest lucru este important, în acest exemplu, am ajuns la metoda non-statică a lui Sayhi () utilizând sintaxa de acces la elementele de clasă statică.

rezumat

  • Principale: Proprietățile statice aparțin claselor, nu obiectelor.
  • Din metoda statică, este imposibil să contactați proprietățile obișnuite și metodele de clasă, $ acest-\u003e Numele nu funcționează aici.
  • Din metoda statică, vă puteți referi la proprietățile statice utilizând numele de sine :: $ nume.
  • Proprietățile de clasă statică nu sunt disponibile obiectelor.
  • Metoda obișnuită se poate referi la o proprietate statică folosind sine :: $ nume.
  • Proprietatea statică poate fi obținută în contextul clasei utilizând sintaxa: TestClass :: $ vârsta.
  • Metoda obișnuită poate fi apelată în context și obiect ($ Object-\u003e Metoda ()) și clasa utilizând sintaxa TestClass :: metoda ().
  • Folosind sintaxa de $ Object :: $ Vârsta am reușit să accesez proprietatea statică prin obiect.

Paralel cu JavaScript

JavaScript are o astfel de clasă de matematică care conține o mulțime de funcții matematice diferite.

Pentru a efectua calcule matematice (calculul sinusurilor sau expoziției) în JavaScript, nu este necesar să se creeze un obiect de matematică de clasă, deoarece metodele sale sunt statice. Înainte de a studia PHP, nu am putut înțelege ce a fost, și doar au studiat clase și obiecte în PHP în capul meu, totul a căzut pe rafturile mele.

De fapt, este foarte convenabil, au acces direct la metodele matematice ale clasei de matematică, evitând crearea obiectelor.

Am vrut mult timp să scriu pe acest subiect. Primul șoc a fost articolul Miško Hevery "Metodele statice sunt moartea la utilitate". Am scris un articol de răspuns, dar nu l-am publicat niciodată. Dar recent a văzut ceva care poate fi numit "programare orientată spre clasă". Acest lucru mi-a revigorat interesul față de subiect și iată rezultatul.

"Programarea orientată spre clasa" este atunci când se utilizează clase constând doar din metode și proprietăți statice, iar instanța de clasă nu este niciodată creată. În acest articol, voi vorbi despre:

  • nu oferă avantaje în comparație cu programarea procedurală.
  • nu renunțați la obiecte
  • disponibilitatea membrilor statici ai clasei! \u003d Testele morții
Deși acest articol despre PHP, conceptele se aplică în alte limbi.

Dependențe

De obicei, codul depinde de celălalt cod. De exemplu:

$ Foo \u003d substr (bara de $, 42);
Acest cod depinde de variabila de bare $ și de funcțiile substrului. $ Bar este doar o variabilă locală definită puțin mai mare în același fișier și în același domeniu. Substr este funcția de kernel PHP. Totul este simplu aici.

Acum, un astfel de exemplu:

Clasa Bloomfilter (... Funcția publică __construct ($ M, $ k) (...) Funcția statică publică Getk ($ M, $ N) (Rotiți ceil (($ M / $ N) * Log (2)) ;) ...)
Această mică funcție auxiliară oferă pur și simplu un ambalaj pentru un algoritm specific care ajută la calcularea unui număr bun pentru argumentul $ K utilizat în constructor. pentru că Trebuie să fie cauzată înainte de a crea o instanță de clasă, trebuie să fie statică. Acest algoritm nu are dependențe externe și este puțin probabil să fie înlocuit. Este folosit astfel:

$ m \u003d 10.000; $ n \u003d 2000; $ B \u003d Bloomfilter nou ($ M, Bloomfilter :: Getk ($ M, $ N));
Nu creează dependențe suplimentare. Clasa depinde de mine.

  • Designer alternativ. Un bun exemplu este clasa datetime construită în PHP. Instanța sa poate fi creată în două moduri diferite:

    $ Data \u003d New DataTime ("2012-11-04"); $ Data \u003d Datetime :: CreațiFromFormat ("D-M-Y", "04-11-2012");
    În ambele cazuri, rezultatul va fi o instanță a datelor și în ambele cazuri codul este legat de clasa datează într-un mod sau altul. Metoda statică Datetime :: CreatFromfromat este un obiect alternativ al obiectului care returnează același lucru cu noul datetime, dar folosind funcționalitate suplimentară. În cazul în care puteți scrie o nouă clasă, puteți scrie și clasa :: metoda (). Nu apar dependențe noi.

  • Utilizarea rămasă a metodelor statice afectează legarea și poate forma dependențe implicite.

    Cuvânt despre abstractizare

    De ce această pauză cu dependențele? Abilitatea de a rezuma! Odată cu creșterea produsului dvs., crește complexitatea acestuia. Iar abstractizarea este cheia managementului complexității.

    De exemplu, aveți o clasă de aplicații, care prezintă aplicația dvs. El comunică cu clasa de utilizator, care este prevenirea utilizatorului. Care primește date din baza de date. Clasa bazei de date are nevoie de baze de dateDriver. Baza de dateDriver au nevoie de setări de conectare. Etc. Dacă pur și simplu apelați aplicația :: Startic () static, ceea ce va determina utilizatorul :: getdata () static, ceea ce va determina baza de date static și așa mai departe, în speranța că fiecare strat se va ocupa de dependențele sale, puteți obține O mizerie teribilă dacă ceva nu merge așa. Este imposibil să ghiciți dacă aplicația :: Start () apel va funcționa, deoarece nu este evident modul în care se vor comporta dependențele interne. Este chiar mai rău că singura modalitate de a influența comportamentul aplicației :: Start () este de a schimba codul sursă al acestei clase și codul de clasă pe care îl solicită și codul de clasă pe care îl apar clase ... în casă Jack a construit.

    Abordarea cea mai eficientă, atunci când se creează aplicații complexe, este crearea unor părți individuale care pot fi respinse în viitor. Părțile care pot fi oprite gândirea în care puteți fi siguri. De exemplu, când apelați baza de date statică :: Fetchall (...), nu există garanții că conexiunea la baza de date este deja instalată sau va fi instalată.

    Funcție (bază de date de bază de date $) (...)
    Dacă este executat codul din această caracteristică - aceasta înseamnă că instanța bazei de date a fost transferată cu succes, ceea ce înseamnă că instanța obiectului de bază de date a fost creată cu succes. Dacă clasa bazei de date este proiectată corect, puteți fi siguri că prezența unei instanțe a acestei clase înseamnă capacitatea de a efectua solicitări în baza de date. Dacă instanța de clasă nu este, corpul funcției nu va fi executat. Aceasta înseamnă că funcția nu trebuie să aibă grijă de starea bazei de date, clasa bazei de date o va face el însuși. Această abordare vă permite să uitați de dependențele și să vă concentrați asupra rezolvării problemelor.

    Fără posibilitatea, nu vă gândiți la dependențele și dependențele acestor dependențe, este aproape imposibil să scrieți cel puțin o aplicație complexă. Baza de date poate fi o clasă de ambalaj mică sau un monstru gigant cu mai multe straturi, cu o grămadă de dependențe, poate începe ca un ambalaj mic și poate muta într-un monstru gigant cu timp, puteți moșteni clasa bazei de date și puteți transfera la funcția descendentă, este Nu este important pentru funcția dvs. (baza de date de bază de date), atâta timp cât interfața publică de bază de date nu se schimbă. Dacă clasele dvs. sunt separate corespunzător de celelalte părți ale aplicației prin implementarea dependențelor, puteți testa fiecare dintre ele folosind prize în loc de dependențele lor. Când ați testat o clasă suficient pentru a vă asigura că funcționează așa cum ar trebui, puteți arunca mai mult inutil de la cap, știind doar că trebuie să utilizați instanța de bază de date pentru a lucra cu baza de date.

    Programarea orientată spre clasă este nonsens. Învață să utilizați oop.

    Reg.ru: domenii și găzduire

    Cel mai mare înregistrator și furnizor de găzduire din Rusia.

    Mai mult de 2 milioane de nume de domenii pentru întreținere.

    Promovare, poștă pentru un domeniu, soluții de afaceri.

    Mai mult de 700 de mii de clienți din întreaga lume și-au făcut deja alegerea.

    * Mouse-ul pentru suspendarea derulării.

    Inapoi inainte

    Metode și proprietăți statice în PHP

    În materialele anterioare, am stăpânit principalele posibilități de programare orientată pe obiecte în PHP și acum mergem la studiul unor aspecte mai complexe și interesante.

    Înainte de aceasta, am lucrat întotdeauna cu obiecte. Am descris clase ca șabloane cu care sunt create obiecte și obiecte - ca componente active, metodele pe care le numim și ale căror proprietăți avem acces.

    De aici, a urmat concluzia că în programarea orientată spre obiect, lucrarea reală se efectuează utilizând cazurile de clase. Și clasele sunt în cele din urmă doar șabloane pentru crearea obiectelor.

    Dar, de fapt, nu totul este atât de simplu. Putem accesa ambele metode și proprietăți în contextul unei clase și nu un obiect. Astfel de metode și proprietăți sunt numite "statice" și trebuie anunțate utilizând un cuvânt cheie static..

    Statice de clasă (static public $ anum \u003d 0; funcția publică statică Sayhello () (Bună ziua! ";))

    Metode statice - Acestea sunt funcții utilizate în contextul clasei. Ei înșiși nu pot primi acces la niciun fel de proprietăți de clasă comună, deoarece astfel de proprietăți aparțin obiectelor.

    Cu toate acestea, din metode statice, așa cum probabil ați ghicit, vă puteți referi la proprietăți statice. Și dacă schimbați proprietatea statică, atunci toate instanțele acestei clase vor putea accesa o nouă valoare.

    Deoarece accesul la elementul static se efectuează prin clasă, și nu printr-o instanță obiect, nu avem nevoie de o variabilă care se referă la obiect. În schimb, se folosește un nume de clasă, după care două culori sunt indicate "::".

    Imprimare StaticexAmple :: $ anum; Staticexample :: Sayhello ();

    Cu această sintaxă, trebuie să fiți familiarizați pe baza OOP din PHP. Am folosit designul "::" în combinație cu un cuvânt cheie mamă. Pentru a avea acces la metoda clasa părinte redefinită.

    Acum, ca atunci, facem apel la clasă și nu la datele conținute în obiect. În codul de clasă, puteți utiliza un cuvânt cheie mamă. Pentru a accesa superclasa, fără a utiliza numele clasei.

    Pentru a accesa metoda statică sau proprietatea din aceeași clasă (și nu de la o clasă pentru copii), vom folosi cuvântul cheie de sine..

    Cuvânt cheie. de sine. Folosit pentru a face apel la clasa actuală și pseudo-distrus $ Acest lucru - la obiectul curent. Prin urmare, din afara clasei Staticexample. Facem apel la proprietate $ Anum. Folosind numele clasei sale.

    Staticexample :: $ anum;

    Și în interiorul clasei Staticexample. Puteți utiliza un cuvânt cheie de sine..

    Statice de clasă (static public $ anum \u003d 0; Funcția publică statică Sayhello () (Selin :: $ anum ++; Imprimare "Hi! (" Sine :: $ anum ") \\ n";))

    Notă: În plus față de cazurile de apel la metoda de clasă primită redefinită, designul "::" ar trebui să fie întotdeauna utilizat numai pentru a accesa metodele sau proprietățile statice.

    Prin definiție, metodele statice nu sunt invocate în contextul obiectului. Din acest motiv, metodele și proprietățile statice sunt adesea numite variabile și proprietăți de clasă. Ca rezultat, este imposibil să se folosească pseudo-distrus $ Acest lucru în metoda statică.

    De ce să folosiți metoda sau proprietatea statică?

    Așa că am ajuns la cea mai importantă problemă. Faptul este că elementele statice au o serie de caracteristici utile.

    in primul randAcestea sunt disponibile din orice punct al scriptului (cu condiția să aveți acces la clasă). Aceasta înseamnă că puteți accesa funcțiile fără a trimite o instanță a clasei de la un obiect la altul sau, chiar mai rău, economisind o instanță a unui obiect într-o variabilă globală.

    În al doilea rând, Proprietatea statică este disponibilă pentru fiecare instanță a obiectului acestei clase. Prin urmare, puteți defini valorile care ar trebui să fie accesibile tuturor obiectelor de acest tip.

    Și, în sfârșit al treileaFaptul că nu are nevoie să aibă o instanță a unei clase de accesare a proprietății sau metodei sale statice va evita crearea de cazuri de obiecte numai pentru a apela o funcție simplă.

    Pentru a demonstra acest lucru, să creăm o metodă statică pentru clasă ShopProduct.care va crea automat cazuri de obiecte ShopProduct.. C Utilizarea Sqlite Determinați tabelul produse. În felul următor:

    Crearea produselor de masă (ID Integer Primary Tastă autoincrement, Tip Text, Text Prenume, Text principal, Titlu Text, Preț Float, NumPages Int, Playlength int, reducere int)

    Acum creați o metodă getinstance ()care trece identificatorul liniei și un obiect de tip DOP. Acestea vor fi utilizate pentru a extrage rândul din tabelul bazei de date, pe baza căreia se formează obiectul de tip. ShopProduct.returnat la programul de apelare.

    Putem adăuga aceste metode la clasă ShopProduct.care a fost creată pentru noi în materiale anterioare. După cum probabil știți, DOP este decriptat ca obiect de date PHP (obiecte de date PHP). Clasa DOP oferă o interfață universală pentru diverse aplicații de bază de date.

    // magazin de clasăProduct privat $ id \u003d 0; Funcția publică SETID ($ ID) ($ id-\u003e id \u003d $ id;) // ... Funcția publică statică Getinstance ($ id, POD $ pdo) ($ stmt \u003d $ pdo-\u003e Pregătiți ("Selectați * de la produse Unde id \u003d? "); $ Rezultat \u003d $ stmt-\u003e execute (matrice ($ id)); $ rând \u003d $ stmt-\u003e pret (); dacă (gol ($ rând)) (return null;) dacă ($ Rând ["Type"] \u003d\u003d "carte") ($ produs \u003d nou produs ($ rând ["titlu"], $ rând ["Firstname"], $ rând ["principal"], $ rând ["preț"] , $ rând ["numpages"]);) altfel dacă ($ rând ["tip"] \u003d\u003d "CD") ($ produs \u003d nou CDProduct ($ rând ["titlu"], $ rând ["Firstname"], $ Rând ["Mainname"], $ rând ["preț"], $ rând ["Playlntength"]);) altceva ($ produs \u003d nou magazin ($ rând ["titlu"], $ rând ["Firstname"], $ rând ["Mainname"], $ rând ["preț"]);) $ Produs-\u003e SETID ($ rând [ID "]); $ produs-\u003e SetDiscount ($ rând [" discount "]); returnați $ produs ;) // ...

    După cum puteți vedea, metoda getinstance () Returnează tipul de obiect ShopProduct., și este suficient "inteligent" pentru a se baza pe valoarea câmpului tip Creați un obiect cu caracteristicile dorite.

    Am coborât în \u200b\u200bmod specific codul de manipulare a erorilor, astfel încât exemplul să fie mai simplu. De exemplu, în versiunea reală a acestui cod, nu putem fi prea încredere și presupunem că obiectul DOP transmis a fost inițial inițializat și conectat la baza de date necesară.

    De fapt, este probabil să încheiem un obiect DOP într-o clasă care garantează un astfel de comportament. Ne vom întoarce la această întrebare într-unul din materialele viitoare.

    Metodă getinstance () Mai util în contextul clasei decât în \u200b\u200bcontextul obiectului. Este ușor să convertiți datele care se află în baza de date la obiect, iar pentru aceasta nu trebuie să avem o instanță separată a obiectului de tip ShopProduct..

    Această metodă nu utilizează niciun fel de metode sau proprietăți care necesită o instanță separată a obiectului, deci nu există niciun motiv pentru a nu declara static. Apoi, având un obiect DOP corect, putem numi această metodă din orice locație de aplicare.

    $ dsn \u003d "sqlite: //home/bob/projects/products.db"; $ Pdo \u003d New DOP ($ dsn, , null); $ Pdo-\u003e setatitribute (DOP :: Attr_ermode, DOP :: Errmode_Exception); $ Obj \u003d magazinproduct :: getinstance (1, $ pdo);

    Astfel de metode funcționează ca o "fabrică", deoarece iau materiale "crude" (de exemplu, date obținute din șirul de bază de date sau fișierul de configurare) și să le utilizați pentru a crea obiecte.

    Termenul "fabrică" se referă la codul conceput pentru a crea instanțe de obiecte. Cu exemple de astfel de "fabrici", ne vom întâlni mai mult cu voi.


    Proprietăți permanente

    Unele proprietăți nu ar trebui să se schimbe. De exemplu, elementele cum ar fi codurile de eroare sau codurile de stare a programului sunt de obicei setate manual în clase. Deși trebuie să fie disponibile publicului și static, codul clientului nu ar trebui să le poată schimba.

    Pentru a face acest lucru, puteți defini proprietățile constante din clasă. La fel ca constante globale, constante de clasă nu pot fi schimbate după ce au fost identificate. Proprietatea permanentă declară utilizând un cuvânt cheie const..

    Spre deosebire de proprietățile convenționale, semnul dolarului nu este pus înainte de numele proprietății permanente. În conformitate cu acordul adoptat, acestea sunt deseori prescrise nume formate din scrisori majuscule, ca în exemplul următor:

    Class Shopproduct (Const disponibil \u003d 0; const out_of_stock \u003d 1; // ...

    Proprietățile permanente pot conține numai valori legate de tipul elementar. Constant nu poate fi atribuit unui obiect.

    Ca și în cazul proprietăților statice, accesul la proprietăți permanente se efectuează prin clasă și nu printr-o instanță a obiectului. Așa cum o constantă este determinată fără un semn de dolar, atunci când accesează-o, nu este de asemenea nevoie să utilizați niciun simbol în față.

    Imprimare magazin :: disponibil;

    Încercarea de a atribui o constantă la valoarea după ce a fost declarată, va duce la o eroare la etapa analiza sintactică.

    Constantele ar trebui utilizate atunci când proprietatea trebuie să fie accesibilă tuturor instanțelor clasei și când valoarea proprietății trebuie fixată și neschimbată.

    Complet acest articol, iar în continuare vom vorbi.

    Ți-a plăcut materialul și vrei să-i mulțumesc?
    Doar împărtășiți cu prietenii și colegii!




    Ți-a plăcut articolul? Împărtășește-l