-
Ah, atmosfera de sarbatori…
Inspirat de o postare in Perl Advent, m-am gandit ca ar fi interesant sa vedem un exemplu cu PHP si Go. Vreau sa mentionez ca acest blog este inspirat intr-o buna masura din postarea mentionata anterior.
Sa presupunem ca vrei sa-i urezi cuiva sarbatori fericite folosind viteza limbajului Go, dar aplicatia ta este scrisa in PHP, ce poti face?
In lumea PHP ar fi momentul ideal, deoarece noua versiune PHP 7.4 vine cu “Foreign Function Interface” (FFI pe scurt).
Echipat cu aceasta noua arma, am instalat PHP 7.4 si am trecut la treaba.
Sa incepem cu super incredibila urare din Go, sa creem fisierul “greeting.go”:
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 WishMerryChristmas(); 9} 10 11func WishMerryChristmas() { 12 fmt.Println("We wish you a Merry Christmas!"); 13}
Si acum sa-l rulam:
1$ go run greeting.go
Ar trebui sa afiseze:
1We wish you a Merry Christmas!
Pana aici e super! Este foarte rapid, frumos si tot ce mai trebuie, dar noua ne-ar trebui sa fie un serviciu, deci sa vedem cum o sa arate in acest caz:
1package main 2 3import ( 4 "C" 5 "fmt" 6) 7 8func main() {} 9 10//export WishMerryChristmas 11func WishMerryChristmas() { 12 fmt.Println("We wish you a Merry Christmas!") 13}
Dupa cum se poate vedea, exista cateva diferente:
- am importat si libraria “C”,
- am scos apelul functiei din main()
- am adaugat un comentariu pentru exportul functiei.
Pentru compilare se ruleaza astfel:
1$ go build -o greeting.so -buildmode=c-shared
De mentionat este faptul ca aceasta comanda trebuie rulata de fiecare data cand fisierul Go este modificat.
Rezultatul ar trebuie sa fie compus din doua fisiere:
“greeting.so” si “greeting.h”.Fisierul de header “greeting.h” contine tipurile de date si definitile functiilor. Daca ai mai lucrat cu C, esti probabil familiarizat cu acest fel de fisiere. In mod normal, tot ce trebuie sa mai facem acum este sa importam fisierul header folosind FFI si sa apelam functia!
Pentru asta am creat un fisier cu numele “greeting.php”:
1<?php 2$ffi = FFI::load("greeting.h"); 3$ffi->WishMerryChristmas();
Pare suficient de simplu, tot ce trebuie sa mai facem acum este sa-l rulam folosind comanda:
1$ php greeting.php 2PHP Fatal error: Uncaught FFI\ParserException: undefined C type '__SIZE_TYPE__' at line 43 in /home/claudiu/php-go/greeting.php:3 3Stack trace: 4#0 /home/claudiu/php-go/greeting.php(3): FFI::load() 5#1 {main} 6 7Next FFI\Exception: Failed loading 'greeting.h' in /home/claudiu/php-go/greeting.php:3 8Stack trace: 9#0 /home/claudiu/php-go/greeting.php(3): FFI::load() 10#1 {main} 11 thrown in /home/claudiu/php-go/greeting.php on line 3
Nu e tocmai urarea la care ma asteptam…
Dupa ce am sapat destul de intens, am gasit asta intr-o pagina de manual:
C preprocessor directives are not supported, i.e. #include, #define and CPP macros do not work.Din acest motiv, se pare ca nu vom putea folosi fisierul de header, sau cel putin eu nu am gasit o metoda clara.
Partea buna este ca putem folosi FFI::cdef() care permite sa specificam definitia functiilor. Daca te-am pierdut pe drum, ce incerc de fapt sa fac este sa-i spun PHP-ului care sunt definitile funcțiilor pe care vreau sa folosesc din fisierul “greeting.so”.
Noul cod va fi:
1<?php 2$ffi = FFI::cdef(" 3void WishMerryChristmas(); 4", __DIR__ . "/greeting.so"); 5 6$ffi->WishMerryChristmas();
Iar daca rulam acum:
1$ php greeting.php 2We wish you a Merry Christmas!
Am progresat mult, iar serviciul isi face treaba foarte bine!
Adaugarea unui parametru int
Urarea arata foarte bine si e super rapida, dar ar fi si mai frumos sa putem specifica de cate ori sa o afisam.
Pentru a face asta, trebuie modificata functia din fisierul “greeting.go”, adaugandu-i un parametru cu numarul afisarilor dorite:1//export WishMerryChristmas 2func WishMerryChristmas(number int) { 3 for i := 0; i < number; i++ { 4 fmt.Println("We wish you a Merry Christmas!"); 5 } 6}
Trebuie rulata din nou comanda de compilare ca mai devreme.
In PHP trebuie sa modificam definitia functiei. Pentru a vedea ce trebuie modificat putem sa ne inspiram din fisierul “greeting.h”. Noua definitie a functiei in fisier este:
1extern void WishMerryChristmas(GoInt p0);
“GoInt”? Ce magie mai e si asta? Daca ne uitam in fisier gasim urmatoarele definitii:
1... 2typedef long long GoInt64; 3... 4typedef GoInt64 GoInt; 5...
De unde concluzionam ca GoInt este de fapt un long.
Cu aceste noi descoperiri putem modifica fisierul PHP in:
1<?php 2 3$ffi = FFI::cdef(" 4void WishMerryChristmas(long); 5", __DIR__ . "/greeting.so"); 6 7$ffi->WishMerryChristmas(3);
Il rulam din nou si vedem:
1$ php greeting.php 2We wish you a Merry Christmas! 3We wish you a Merry Christmas! 4We wish you a Merry Christmas!
Ah, incepe sa se simta spiritul sarbatorilor!
Adaugarea unui parametru string
Sa afisam o urare de mai multe ori este destul de dragut, dar ar fi mai dragut sa adaugam si un nume.
Noua functie devine:
1//export WishMerryChristmas 2func WishMerryChristmas(name string, number int) { 3 for i := 0; i < number; i++ { 4 fmt.Printf("We wish you a Merry Christmas, %s!\n", name); 5 } 6}
Nu uita sa compilezi, iar apoi vom trece la partea interesanta.
Daca ne uitam in fisierul “greeting.h”, noua definitie a functiei este:
1extern void WishMerryChristmas(GoString p0, GoInt p1);
Stim deja ce este GoInt, dar GoString este un pic mai complicat. Dupa mai multe substituiri am ajuns la structura:
1typedef struct { char* p; long n } GoString;
Este practic un pointer catre o lista de caractere si o dimensiune.
Asta inseamna ca, in fisierul PHP, noua definitie o sa fie:
1$ffi = FFI::cdef(" 2typedef struct { char* p; long n } GoString; 3typedef long GoInt; 4void WishMerryChristmas(GoString p0, GoInt p1); 5", __DIR__ . "/greeting.so");
p0 si p1 sunt optionali, dar i-am lasat ca sa semene mai mult cu definitia din fisierul de header.
Similar, GoInt este practic un long, dar l-am lasat acolo din acelasi motiv.Construirea unui GoString din PHP a fost un pic mai complicata. Principala cauza a fost ca nu am gasit un mod sa fac un “char *” si sa-l initializez in acelasi timp. Alternativa mea a fost sa fac un array de “char” si apoi sa-i fac cast, dupa cum urmeaza:
1$name = "reader"; 2$strChar = str_split($name); 3 4$c = FFI::new('char[' . count($strChar) . ']'); 5foreach ($strChar as $i => $char) { 6 $c[$i] = $char; 7} 8 9$goStr = $ffi->new("GoString"); 10$goStr->p = FFI::cast(FFI::type('char *'), $c); 11$goStr->n = count($strChar); 12 13$ffi->WishMerryChristmas($goStr, 2);
Sa-l incercam:
1$ php greeting.php 2We wish you a Merry Christmas, reader! 3We wish you a Merry Christmas, reader!
Succes!
In aceasta faza, mi-ar placea sa mut crearea de GoString intr-o functie separata, de dragul lizibilitatii codului.
Noul cod rezultat este:
1$name = "reader"; 2 3$goStr = stringToGoString($ffi->new("GoString"), $name); 4 5$ffi->WishMerryChristmas($goStr, 2); 6 7function stringToGoString($goStr, $name) { 8 $strChar = str_split($name); 9 10 $c = FFI::new('char[' . count($strChar) . ']'); 11 foreach ($strChar as $i => $char) { 12 $c[$i] = $char; 13 } 14 15 $goStr->p = FFI::cast(FFI::type('char *'), $c); 16 $goStr->n = count($strChar); 17 18 return $goStr; 19}
Si acum sa-l incercam:
1$ php greeting.php 2We wish you a Merry Christmas, ��! 3We wish you a Merry Christmas, ��!
Hopa, nu e tocmai bine… pare ca afisam niste memorie reziduala. Dar de ce?
Cautand in documentatia FFI::new am gasit un al doilea parametru, “bool $owned = TRUE”.
Whether to create owned (i.e. managed) or unmanaged data. Managed data lives together with the returned FFI\CData object, and is released when the last reference to that object is released by regular PHP reference counting or GC. Unmanaged data should be released by calling FFI::free(), when no longer needed.
Asta inseamna ca atunci cand intoarcem rezultatul functiei, GC-ul din PHP dezaloca memoria pentru variabila cu string-ul. Este destul de probabil ca acesta sa fie un bug, dar exista o solutie foarte simpla, trebuie doar sa adaugam “false” la crearea de array:
1$c = FFI::new('char[' . count($strChar) . ']', false);
Sa incercam din nou:
1$ php greeting.php 2We wish you a Merry Christmas, reader! 3We wish you a Merry Christmas, reader!
Si functioneaza!
Concluzie
Poate ca rulatul din PHP a unei librarii scrisa in Go nu este atat de simplu precum importul unui fisier de header, dar cu putina rabdare nu este nici foarte dificil! Marele avantaj este ca librariile scrise in Go, sau in orice alt limbaj de programare care permite acest lucru, pot fi folosite din PHP fara sa mai trebuiasca reimplementarea lor!
Si, încheind pe aceasta nota pozitiva, va urez sarbatori fericite!
-
Cum sa folosesti Xiaomi Air Conditioning Companion in Home Assistant in doar de 20 pasi usor de urmat!
Oct 13, 2019 homeassistantPasul 1:
Cumpara un Xiaomi Air Conditioning Companion fara sa te uiti prea in detaliu cat de bine se integreaza cu Home Assistant.
Pasul 2:
Realizeaza ca, în China, priza de 16A este diferita de cea de 10A.
Pasul 3:
Da-ti seama ca nimeni nu vinde in Romania adaptoare de la 10A la 16A pentru China.
Pasul 4:
Cumpara un stecher de 16A din China.
Pasul 5:
Asteapta cam 2 luni sa ajunga din China atat adaptorul cat si dispozitivul.
Pasul 6:
Realizeaza ca nimeni nu vinde nici adaptor pentru priza la schuko.
Pasul 7:
Gaseste singurul comerciant care vinde modul de priza pentru priza chinezeasca, probail din greseala
Pasul 8:
Asteapta sa te caute comerciantul si sa-ti spuna ca dureaza cam o luna sa livreze modulul.
Pasul 9:
Asteapta cam o luna ca sa fie livrat modulul.
Pasul 10:
Instaleaza modulul de priza si stecherul.
Pasul 11:
Conecteaza Xiaomi Air Conditioning Companion la priza si aerul conditionat la Companion pentru prima data.
Pasul 12:
Realizeaza ca Xiaomi Mi Home App a fost updatat intre timp si nu exista niciun tutorial functional care sa-ti arate cum sa obtii parola pentru Home Assistant.
Pasul 13:
Gaseste un mod de a lua parola, dupa multe incercari.
Pasul 14:
Adauga parola de la pasul anterior in Home Assistant si constata ca singurul lucru pe care-l poti face din Home Assistant este sa suni alarma si sa-i schimbi volumul.
Pasul 15:
Gaseste modulul xiaomi_airconditioningcompanion si realizeaza ca de fapt nu aveai nevoie de parola gatewayului.
Pasul 16:
Fa downgrade la Xiaomi Mi Home App si obtine tokenul urmarind instructiunile de la: https://www.home-assistant.io/integrations/vacuum.xiaomi_miio#retrieving-the-access-token
Pasul 17:
Da-ti seama ca nu ai versiunea potrivita de Hass.io pentru a folosi modulul.
Pasul 18:
Migreaza la Hassbian de la Hass.io
Pasul 19:
In sfarsit, instaleaza extensia si seteaza modulul.
Pasul 20:
Singurul lucru care mai ramane de facut este sa te bucuri de confortul oferit de controlatul aerului conditionat de la cativa metri distanta, fara a avea nevoie de telecomanda!
-
Nota
Trebuie mentionat ca aceasta solutie este adaptata nevoilor mele, deci exista posibilitatea ca ele sa nu se suprapuna perfect cu nevoile tale. Totusi nu-ti face griji, totul este pe GitHub, asa ca poti lua doar ce ai nevoie.
Vreau sa mai adaug si ca acesta nu este blog de genul “ai folosit total gresit Magento2 cu Docker pana acum, uite cum se face de fapt”, eu doar vreau sa-mi impartasesc experienta. Probabil ca nu este cea mai buna solutie pentru toata lumea, dar cred ca orice persoana interesata de subiect poate gasi ceva util aici.
Intro
De aproape 2 ani folosesc Magento2 in containere Docker. Am facut asta si inainte, dar trebuie sa recunosc ca a fost pentru ca a trebuit, nu pentru ca am vazut calea cea buna, adica avantajele Docker.
Dupa cum probabil ai aflat deja, Magento2 nu este tocmai o aplicatie micuta si usoara, este chiar foarte greoi, lucru vizibil in special in timpul dezvoltarii.
Daca l-am compara cu un VM clasic, cu Docker ai avea in plus:
- Viteza: cred ca acesta este unul dintre cele mai mari avantaje, poti opri si porni containerele foarte rapid, doar primul build dureaza mai mult, dupa asta totul va fi foarte rapid;
- Mai putine resurse utilizate: Comparat cu un VM, un container nu trebuie sa includa tot sistemul de operare, in consecinta nu va ocupa mult spatiu pe disc si nu va folosi foarte multa putere de procesare, iar pentru ca nu este un OS intreg nu face toate lucrurile… de OS, in general face doar actiuni legate de serverul relevant.
Dar ce nu primesti in schimb:
- Curba de invatare: daca nu ai cunostinte de Docker si Docker Compose, o sa fie mai putin intuitiv la inceput;
- Prima instalare: este mai greu de setat la inceput, iar daca ai folosit VM-uri mult timp o sa ai impresia ca mergi impotriva curentului, dar cu siguranta o sa devina mult mai usor pe termen lung.
Luand cele de mai sus in considerare, vreau sa mentionez ca atunci cand am facut acest setup foloseam un Linux cu 8Gb de RAM. Un coleg chiar mi-a urat succes in a instala Magento2 pe un calculator ultraportabil cu 8Gb de RAM. Nici macar nu era sarcastic, era mai degraba compasiune legata de decizia mea proasta in a-mi alege calculatorul de lucru.
O alta nevoie a fost sa am izolare si configuratii specifice intre proiecte, nu puteam sa instalez un server pe local si gata.
In trecut am folosit Vagrant si VirtualBox, o combinatie foarte buna, foarte usor de folosit (in mare parte). Dar pentru Magento2, am realizat ca avea nevoie de prea multe resurse si calculatorul meu nu facea fata.
Totodata trebuia sa fie si usor de folosit, nu-mi place sa scriu comenzi de 3 cuvinte din memorie, vreau doar sa apas tab de cateva ori si sa se rezolve totul.
Cerintele
Au fost cateva cerinte specifice:
- nginx config – trebuia sa meraga din prima, iar fisierul de configurare pentru Magento 2 nu e tocmai mic si usor de folosit;
- SSL – domeniul trebuia sa mearga si cu HTTPS, in mare parte din pricina API-urilor care aveau nevoie de o conexiune HTTPS, chiar daca certificatul nu este valid;
- bash – comenzile de Magento trebuiau sa fie rulate cu utilizatorul de pe sistemul gazda, nu ca root (asa cum ruleaza in general containerele). Aveam nevoie de asta ca sa nu fie probleme de drepturi intre fisierele generate de mine si cele generate de Magento.
- xdebug – trebuie sa ruleze out of the box si sa fie usor de integrat cu un IDE.
Implementare si intrebuintare
Magento2 oferea un container Docker pentru dezvoltare. Nu vreau sa spun nimic de el, pentru ca nu era deloc ce imi trebuia.
Sursa mea principala de inspiratie a fost: https://github.com/markoshust/docker-magento. Proiectul s-a schimbat foarte mult in ultimii 2 ani, dar merita sa-i acordati cateva minute.
Punctul de inceput este: https://github.com/claudiu-persoiu/magento2-docker-compose
Fisierele relevante sunt:
- magento2 – ar trebui sa contina un folder html in care se afla proiectul;
- dkc_short – poate sa stea oriunde, dar ar trebui adaugat la ~/.bash_profile or ~/.bashrc, acest fisier contine alias-uri si scurtaturi, nu este neaparat necesar dar mie imi face viata mai usoara;
- docker-compose.yml – contine toate maparile si containerele relevante.
NOTA: Cred ca ar trebui sa mentionez ca in containerul PHP se pot rula comenzi in doua feluri, ca utilizator de sistem sau ca root. Aceasta limitare este datorata modului in care ruleaza containerele in Linux, o sa revin la acest subiect mai tarziu.
Pasul 1:
Ce trebuie facut atunci cand vrei sa rulezi un proiect Magento2 existent:
1$ git clone https://github.com/claudiu-persoiu/magento2-docker-compose.git nume_proiect 2$ cd nume_proiect 3$ git clone calea_catre_repository magento2/html
Pasul 2 (optional):
Copierea alias-urilor in consola bash:
1$ cp dkc_short ~/ 2$ echo ~/dkc_short >> ~/.bash_profile 3$ source ~/.bash_profile
NOTE: Daca nu exista fisierul ~/.bash_profile atunci trebuie folosit ~/.bashrc
Pasul 3:
Pornirea containerelor:
1$ dkc-up -d
Va dura mai mult prima data, dar de data viitoare va fi mult mai rapid.
Pasul 4:
Instalat dependinte folosind composer:
1$ dkc-php-run composer install
Cam asta e tot.
Ce e chestia asta cu dkc?
Dupa cum spuneam, imi place sa folosesc tab cand scriu o comanda, asa ca mi-am adaugat cateva alias-uri care imi permit sa rulez comenzi fara sa tastez tot. De exemplu dkc[tab]p[tab]-[tab] si restul comenzii. Iubesc autocomplete-ul din bash.
Lista de comenzi este foarte simpla:
- dkc-up -d – pornesc toate containerele in background
- dkc-down – opresc toate containerele
- dkc-mag [command] – ruleaza o comanda Magento2
- dkc-clean – curata cache-ul
- dkc-php-run – ruleaza o comanda bash in containerul de PHP, cum a fost composer in exemplul anterior. NOTA: aceasta comanda ruleaza ca utilizator de sistem, nu root
- dkc-exec phpfpm [command] – la fel ca mai sus dar dar ruleaza ca root. In majoritatea cazurilor va fi nevoie doar de comanda de mai sus;
- dkc-exec [container] [command] – aceasta comanda are nevoie de explicatie mai extinsa:
- poate sa fie:
- app – pt serverul Nginx,
- phpfrm – pentru containerul PHP,
- db – pentru baza de date,
- cache sau fpc – pentru cache;
- aceasta comanda poate sa fie orice se aplica la un container, precum “bash” sau “bash composer”, etc.
- poate sa fie:
Stiu ca toate comenzile par ca mai adauga ceva de invatat, dar in mare parte din timp doar primele 4 sunt necesare.
Cum functioneaza toata magia?
Pai, comenzile de mai sus se pot vedea in fisierul “dkc_short”.
Mai sunt doua repositories de interes:
- https://github.com/claudiu-persoiu/magento2-docker-php – containerul phpfpm,
- https://github.com/claudiu-persoiu/magento2-docker-nginx – containerul cu serverul nginx.
Repository-urile sunt destul de mici si relativ usor de inteles.
Daca ai nevoie sa modifici ceva, poti face un fork fara grija.
Concluzia
Cam asta e tot ce este de stiut, eu folosesc aceasta configuratie de aproape 2 ani.
Pentru mine functioneaza fara probleme si am putut sa folosesc Magento2 pe un calculator ultraportabil cu 8Gb RAM fara niciun neajuns.
Final (fericit)!
-
Nu te lasa pacalit, aceasta postare chiar este despre programare, arhitectura sistemelor, dar si despre un sistem de incalzire.
Daca nu-ti dai seama cum poti vorbi despre programare fara sa folosesti programare, atunci ar trebui sa citesti cartea “The Passionate Programmer” de Chad Fowler, este o carte foarte buna. Povestirile legate de jazz din acea carte m-au inspirat sa scriu aceasta postare.
Povestea incepe intr-un apartament nou dintr-o cladire veche. Sau cel putin, e nou pentru mine.
Cladirea are o centrala proprie, foarte veche si extrem de ineficienta. Dupa o lunga analiza, am decis sa-mi instalez propria centrala de apartament si sa ma deconectez de la sistemul de incalzire al cladirii.
Pana aici nimic deosebit, multa lume face asta, parte pentru confort, parte pentru optimizarea cheltuielilor.
Acestea fiind spuse, aveam un proiect si aveam nevoie de un dev. Sau, cu alte cuvinte, aveam un sistem de incalzire de facut si aveam nevoie de cineva care sa-l construiasca.
Am intrebat in jur de un dev “bun”.
Ca in orice alt domeniu, sunt multi oameni care vin cu solutii proaste. Sunt unii care fac oferte foarte bune, dar nu sunt capabili sa termine lucrarea, sau scriu cod urat care nu este scalabil, sau, si mai rau, imposibil de mentinut.
Avand in vedere ca tot ce stiu despre centrale si sisteme de incalzire este cam ce stie oricine dupa ce a cautat subiectul pe google pentru aproximativ doua ore, am vrut pe cineva in care sa am incredere, asa ca am cautat dev-ul pasionat!
Am avut cateva recomandari. Primul mi-a spus ca trebuie sa-mi pun tevile aproape de travan. Dupa ce l-am convins ca nu vreau ca apartamentul meu sa arate ca o fabrica plina de tevi mi-a spus ca in mod sigur trebuie sa inlocuiasca (cel putin) un calorifer pentru ca nu poate trage o teava prin spatele lui. Aproape ca puteam sa-mi bag toata palma in spatele caloriferului asa ca am concluzionat ca cel care vine trebuie sa fie capabil sa treaca testul de a trage o teava prin spatele caloriferului.
Era evident ca nu era un dev bun. Un bun dev trebuie sa poata lucra cu cerintele, un proiect trebuie sa respecte cat mai multe din cerintele clientului, iar daca nu poate atunci sunt cateva explicatii: nu poate pentru ca nu stie cum sau nu vrea pentru ca stie ca este greu si nu vrea sa se complice. In unele cazuri asta nu este o tragedie, poate este mai ieftin si mai rapid, iar in cazul lui ar fi fost. Din pacate pentru el, eu eram interesat de calitate.
Si apoi a aparut programatorul pasionat. Nu a spus la niciun moment ca este ceva ce nu poate face, era mereu vorba doar de un cost si, poate, de o consecinta. Can lucrezi cu un dev mai, totul legat de ei e mai scump, nu doar munca lor: vor vrea servere mai bune, unelte mai bune si uneori mai mult timp pentru lucruri precum testare si mententanta. Cu alte cuvinte, uneori pretul este mai mare, nu doar pe loc, ci si pe termen lung. Un proiect de calitate necesita timp si bani.
Acesta este rezultatul proiectului meu:
In caz ca nu ai mai vazut un sistem de incalzire pentru un apartament, poate ar trebui sa stii ca, in afara de tevi, nimic altceva nu este neaparat necesar.
Este doar pasiune!
De exemplu: pompa din dreapta jos, este acolo doar ca sa forteze apa sa se miste mai repede prin instalatie. Gandeste-te la ceva de tipul Redis, care va avea un efect benefic asupra sistemului, dar majoritatea sistemelor vor lucra foarte bine fara el. Evident, la un moment dat ar putea chiar avea nevoie de mententanta sau poate creea si probleme, ca aceasta problema din Magento 2: https://github.com/magento/magento2/issues/10002. Orice sistem vine cu pretul lui.
Vasul de expansiune din stanga jos nu era necesar (in sensul in care centrala are deja unul integrat), dar nu este o idee rea sa ai unul in plus. Este ca si cum ai resurse suplimentare (spatiu de stocare suplimentar, ram sau CPU) pe care nu le folosesti, de fapt, in mod constant. Un server nu ar trebui in general sa depaseasca un anumit load, acela este vasul de expansiune al serverului pe care trebuie sa-l iei in considerare.
Filtrul de apa este ca un firewall, ai nevoie de el, este protectia ta, poate marea majoritate a timplui va fi inutil, dar atunci cand vei avea probleme pe instalatie iti va parea bine ca il ai, pentru ca el le va filtra.
Partea buna cu un dev pasionat este ca si alti devi ii inteleg si ii apreciaza munca. Asta este foarte important, indiferent de industria “dev-ului”.
Singurul care a avut ceva de comentat a fost tehnicianul care facea ISCIR-ul. Puteai sa-ti dai seama foarte usor ca nu e pasionat, a vrut sa spuna ceva de rau doar ca sa ma impresioneze pe mine cu expertiza lui.
Din pacate pentru el, a facut niste comentarii foarte ridicole dupa care mi-a facut o oferta de mentenanta. El era consultantul, nu a facut proiectul si nu a vrut sa munceasca la el, dar in mod sigur vrea sa faca un ban din el fara sa depuna niciun fel de efort.
Cred ca o concluzie este ca intre developeri, calitatea si pasiunea transcend industria.
-
De curand am trecut examenul pentru Zend Certified Engineer 2017, certificare oferita de Rogue Wave.
Desi experienta este cel mai important lucru pentru o certificare, cartile sunt cel mai bun mod de a-ti largi cunostintele, in opinia mea.
Pentru ca o certificare este ceva foarte specific, nu sunt foarte multe carti relevante disponibile.
Inainte de a incepe, trebuie notat ca cea mai exhaustiva resursa pentru a invata PHP este manualul, intotdeauna trebuie trecut prin toate clasele si functiile care sunt disponibile.
Zend Certified Engineer Exam Study Guide 20$
Am cumparat aceasta carte doar pentru ca am vrut sa-i fac un review si sa-mi castig dreptul de a-mi exprima parerea despre ea.
Acest ghid a fost introdus cu certificarea pentru PHP 5.3 si pe atunci era gratuit. Calitatea cartii s-a imbunatatit continuu intre timp, dar niciodata foarte mult, iar de la un moment nu a mai fost o resursa gratuita.
Am sperat ca in timp o sa devina din ce in ce mai bun, dar nu a fost asa. Este o carte scurta, cu font mare si multe, multe greseli.
Singura parte buna este ca la fiecare capitol exista intrebari. In afara de asta nu este o resursa prea buna si in mod sigur nu valoreaza 20$, probabil 5$ era mai aproape de realitate, avand in vedere ca de la o versiune la alta doar au actualizat-o doar cate putin si doar au adaugat noile schimbari si aditii din limbaj. Nici macar intrebarile nu par sa se schimbe prea mult in timp.
Asa ca daca vei cumpara o singura carte, mai bine sa o cumperi pe urmatoarea.
PHP 7 Zend Certification Study Guide – Andrew Beak – Apress 2017 – 19.99$
Cartea analizeaza in mai mult detaliu toate sectiunile din certificare, are peste 300 de pagini.
Aceasta carte arata mai mult ca o carte de programare decat un ghid. Calitatea cartii este mult mai buna decat cea a ghidului oficial, dar asta nu e dificil daca luam in considerare cat de slaba este calitatea aceluia.
Si in aceasta carte sunt intrebari dupa fiecare capitol, lucru util pentru a-ti testa cunostintele intr-un format apropiat examenului. Totusi intrebarile par un pic mai “blande” decat ghidul, examenul in sine are multe intrebari foarte “tricky”.
Evident acest ghid nu este chiar complet, nu poti avea cu adevarat un ghid care sa trateze absolut toate detaliile intr-o singura carte si, chiar daca ar exista, probabil nu ai avea timp sa o citesti.
Daca vei cumpara o singura carte, recomandarea mea este sa o iei pe aceasta, pentru ca este o carte, nu doar un ghid la nivel foarte inalt (si calitate joasa).
Zend PHP 5 Certification Study Guide, Third Edition – php[architect] – 22$
Daca ai impresia ca am gresit versiunea, ce pot spune? Ai dreptate!
Am vrut sa adaug si aceasta carte la lista pentru ca, pentru mine, a fost cel mai bun ghid de studiu. De-a lungul anilor au fost mai multe ghiduri, dar acesta mi-a placut cel mai mult.
Pentru certificarea de PHP 5 nu exista un ghid oficial de la Zend, doar prima editie din aceasta carte. A fost o carte de programare interesant de citit. Uneori cand vreau sa-mi reamintesc ceva ce nu am mai folosit de multa vreme, sau deloc, citesc capitolul din aceasta carte.
Cand am dat examenul pentru certificarea de PHP 5.5 (pentru ca a trebuit sa le am pe toate), am fost placut surprins sa aflu ca exista o noua versiune a aceastei carti.
Este in esenta aceeasi carte, dar actualizata pentru noua certificare. Poate doar imi place mine stilul de a scrie al lui Davey Shafik.
Cartea imi da senzatia ca e mai plina de informatii, mi se pare ca aduce mai mult cu un ghid de studiu decat cartea precedenta.
Totusi, aceasta carte nu are intrebari si nu mai este de actualitate.
Daca ai timp, poti sa o citesti oricum, eu o consider o carte buna de PHP.
Concluzii
Nu exista prea multe carti pentru aceasta vertificare, dar daca ar trebui sa aleg o singura recomandare, probabil ar fi: “PHP 7 Zend Certification Study Guide” de la Apress.
Din pacate nu prea exista competitie, pentru ca “Zend PHP 5 Certification Study Guide, Third Edition” de la PHP Arch nu mai este de actualitate, iar ghidul oficial pur si simplu nu valoreaza 20$.
Daca seful tau iti cumpara cartile, eu sugerez sa le iei pe toate! Pana la urma costa: 20$ + 19.99$ + 22$ = 61.99$! Nu e rau pentru trei carti de programare!