Help! HTML

La mine e un mini-workflow la care fiecare pas dureaza maxim o secunda, daca nu ar fi nevoie de o temporizare pentru a lasa timp sa se intample niste sincronizari externe (Enterprise Directory cu Active Directory si SAP, zeci de servere pe toate continentele, dureaza in practica pana la 10 minute) ar fi un singur program care sa faca totul, monobloc. Nu exista nici o aplicatie care sa interactioneze cu acest workflow, doar crearea elementelor noi se face de o alta aplicatie dar se pun intr-o tabela in baza de date si cam atat.

Nu e nimic serios, doar ma distrez un pic pentru ca am ramas fara developerul de PHP care a fost rechizitionat temporar de un proiect critic, de tipul care se ocupa de UI (HTML & Javascript) care e tot temporar in alt proiect, un alt developer de PHP disponibil nu e familiar deloc cu sistemele interne si ce trebuie sa faca fiecare pas in workflow e mai usor de scris decat de explicat, asa ca macar incerc sa le dau baza pe care sa construiasca mai departe. Dezvoltator in C# nu am in proiectul asta, dar la cat e de simpla treaba pot sa scriu eu cele sub 1000 de linii de cod estimate; problema e ca daca ma apuc sa il scriu in C# va trebui sa il fac eu de mana, complet, pe cand daca il fac in PHP pot sa scriu nucleul functional si sa il las developerului sa ii scrie toata partea de tratare de erori si documentatia. In ultima vreme am mai facut asa pe partea de UI, am scris nucleul si l-am lasat pe specialist sa il faca sa arate frumos, sa curete si documenteze partea de CSS etc., dificultatea e ca dezvoltatorii sunt externi si nu inteleg nici ce ne trebuie noua ca proces si nici unde se afla diverse chestii si cum se interactioneaza cu ele; procesul si harta sistemelor sunt mult mai complicate decat aplicatia :smile:
 
Zici că ai apeluri de servicii web și trimitere de mail-uri, un timeout la conectarea lau un server îți poate adăuga mult timp de rulare.
 
Corect, timeout cam 1 minut in general, iar dracia ruleaza o data la 15 minute, deci nu e o problema. Nu exista o aplicatie care sa ruleze permanent ca sa pot sa fac un scheduler in ea, e doar un script/mini-aplicatie care ruleaza din cand in cand precum bancul cu "nu sunati la usa, mai ies eu din cand in cand".
 
Last edited:
https://www.devside.net/wamp-server/running-php-scripts-as-cron-jobs-on-windows

Deci rulezi liniștit PHP-ul folosind Task Scheduler-ul și nu-ți faci alte probleme. Interpretorul PHP nu va fi apelat în acest caz de o instanță a serverului web, ci direct de scheduler, unde setezi timeout-ul și ce mai vrei. Ar mai fi de verificat doar userul sub care rulează task-ul, să nu te trezești că-ți blochează contul de rețea sau că nu rulează fiindcă n-are destule permisiuni.
 
Ca se poate, stiam, de-aia am luat varianta asta in calcul. Ce nu imi place, insa, e ca in caz de probleme se comporta ca un idiot: in diverse cazuri ori nu merge cate o bucata de cod perfect valida, ori merge pentru un user si nu merge pentru altul, ori crapa fara sa scrie nimic in logul de erori al PHP-ului. Daca nu ar fi atat de aleator alegerea ar fi mai simpla, ca tot am ceva cod gata scris, in schimb C# nu a crapat vreodata daca a trecut de compilare decat in caz de erori netratate, care apar exclusiv din vina cui a scris codul. Am trimis o intrebare la tipa din Filipine care o sa aibe in grija toata aplicatia pe viitor (sunt mai multe bucati la mijloc), in cateva ore vad ce zice si daca e de acord cu C# ma apuc sa scriu tot in C#. Din pacate ea nu stie o boaba de programare in orice limbaj (doar e IT manager; dupa cum se lauda o romanca de-a noastra din Sibiu ca "ea e IT manager, nu a scris o linie de cod din facultate"), asa ca intrebarea e din categoria "iti place sa vezi filmele in klingona sau subtitrate in romulana?" si raspunsul ar putea fi "da, o sa analizam si vedem cum facem" cu un raspuns clar dupa data de punere in productie ca sa rezolve problema responsabilitatii :frown:
 
Eu cred totuși că în 20 de ani au avut timp să facă până și PHP-ul determinist, doar că unele metode de tratare a erorilor sunt mai proaste, obscure sau doar nefolosite (die() e încă folosită ca error handling), iar faptul că nu sunt toate căile de rulare verificate (să dea eroare runtime pentru că nu se poate interpreta bucata de cod) e o problemă de testare mai mult.
 
Cateva exemple simple:
1. Intamplat de mai multe ori: scris o bucatica de cod intr-un PHP, testat, copiat intr-un segment mai mare, nu merge; comentat linie cu linie pana cand nu da nici o eroare, decomentat linie cu linie, merge. Diferenta intre fisierul original si cel final e aparent zero. Alta varianta e cea mentionata deja, copy/paste nu merge, sters si scris din nou de mana linia respectiva merge.
2. O pagina se deschidea si mergea impecabil pentru mine, dar pentru nimeni altcineva. Comentat codul pana afisa ceva, aparent avea treaba cu baza de data - singura diferenta intre mine si ceilalti era ca eu eram admin in baza de date, ceilalti nu, dar accesul se facea cu username si parola. Pierdut timp, nu avea nici o treaba cu asta, am descoperit ca un camd de tip data era afisat corect pentru mine si datea erori pentru ceilalti, nu am descoperit niciodata de ce pentru ca PHP-ul respectiv genera o pagina de web cu fix aceleasi date, nu era absolut nimic diferit de la un utilizator la altul.
3. O pagina tot dadea erori; ma uit in log, ultima eroare era din ziua precedenta si era de la o pagina care mergea, nimic de la cele care nu mergeau. Optiunile de erori erau activate toate, inclusiv cele de parsing.
4. Erau niste probleme server side cu apeluri AJAX; pe acelasi calculator in browsere diferite response body era ori foarte detaliat despre eroarea produsa, ori complet opac (eroare 500 fara nici un fel de detalii), dar chiar si cu acelasi browser comportamentul diferea de la o zi la alta.

Nu mai zic nimic despre cat de mult difera comportamentul browserelor la debugging de Javascript (pentru Ajax), cu plusuri si minusuri serioase pentru Chrome versus Edge, de pilda, astfel incat le foloseam pe amandoua in acelasi timp ca sa aflu ce se intampla (Edge da mesaje de eroare mai clare, dar crapa deseori in timp ce faci debug; Chrome nu crapa, dar reseteaza formurile la submit de capul lui).

Toate astea fac ca scrierea de cod in PHP sa fie 5% scris si 95% depanat, ca timp. In C# e fix invers, pentru ca IDE-ul iti spune pe loc daca ai facut o prostie si e destul de clar in a spune despre ce e vorba.
 
PHP e un interpretor ce face parsing linie cu linie la cod, nu face error checking și compilare în avans. Când se mai întâmplă chestii de-astea dubioase, de curiozitate vezi dacă nu cumva la copy&paste s-au luat și niște caractere mai dubioase (encoding, de-astea). E posibil ca codul sursă să trebuiască sanitizat. Eventual trece copy&paste mai întâi prin Notepad pentru a scăpa de ceva caractere ascunse.

Avantajul PHP-ului e de a fi mai ușor integrat cu serverul web și SQL. Poate să mai fie un avantaj situația în care ai un developer PHP căruia să-i poți da să codeze ce-ți tună prin cap. Dar altfel, PHP nu e deloc cea mai bună alegere pentru orice scenariu posibil. Personal aș prefera și un PowerShell decât să rulez task-uri locale în PHP.
 
Da, e interpretor, dar la rulare verifica intai tot fisierul, nu porneste daca exista erori de parsing; desi are optiune de a include in log erorile de parsing (teoretic imposibile in productie, ca daca a rulat vreodata si nu s-a modificat nimic nu ar avea cum sa dea erori la rularile ulterioare), nu o face.

Copierile respective erau din Notepad ++ in Notepad ++, dintr-un fisier php care rula in altul care nu rula. Daca le copiam de pe un site de warez (daca mai exista asa ceva) intelegeam perfect, chiar m-as fi asteptat la asa ceva si as fi fost usor dezamagit daca nu s-ar fi intamplat nimic (poate ca s-a intamplat ceva, dar nu stiu eu :smile: ), dar in acest caz nu am alta explicatie decat sfantul duh in care si-a bagat dracu' coada :dracu:

Oricum s-a lamurit problema, tufa noastra din Manila a decis ca vrea PHP pentru ca o sa o coste mai putin suportul daca e un singur limbaj, ca de la furnizorii nostri primim specialisti la nivelul la care abia isi leaga sireturile la pantofi si stiu cate ceva intr-un singur limbaj de programare, al doilea e exclus din start pentru ca pana si ei ar prefera ca al 3-lea skill, daca ar exista, sa fie sa se incheie si la pantaloni (se pare ca aia care o fac umbla desculti, confirmand limita de 2 skills per om). Deci cu drag si spor m-am apucat de scris PHP.

Avantajele pe care le mentionezi sunt reale, chiar scrii putin cod pentru asa ceva; ca sa adaugi un maruntis intr-o pagina de web e banal sa pui un mic paragraf de 3-4 randuri care incepe cu <?php si se termina cu ?> in care se mai leaga si la o baza de date si citeste ceva aleator de acolo :smile: Dintr-un punct de vedere e mai simplu decat in C# unde acelasi lucru se poate face in 5 moduri si trebuie sa fii extraordinar de bun ca sa te prinzi care sunt diferentele intre ele, la mine e doar un soi de spaghetti code cu bucati care functioneaza fara sa aibe alt fundament stiintific in spate decat ca scria prin vreun manual la exemple "cum sa faci asta". Din cauza asta dupa ce imi termin joaca prin bucatarie dau codul unor specialisti care il curata si optimizeaza, nu mi-as pune hieroglifele in productie.
 
Nu e vorba de HTML, dar cum nu avem nici un topic "Help! Programare" sau "Programare: cum fac?" si ca sa nu mai creez inca unul pentru o discutie de 3 raspunsuri, intreb aici.

Am o pagina care afiseaza un grafic destul de simplu folosind Google Charts. E vorba de niste serii saptamanale pe maxim 2-3 ani (deocamdata doar 6 luni), deci in total vreo 100-150 de seturi de cate 3-4 valori, maxim 600 de numere in total. Cum am doar vreo 100 de valori.

Am pus seriile manual in pagina (ca array), totul merge. Seriile de date vin din niste database views cam lente, sunt milioane de inregistrari in spatele lor, per total vreo 15-20 de secunde; avand in vedere ca sunt serii temporale tot ce e mai vechi de saptamana trecuta nu se modifica niciodata, in loc de a le calcula la fiecare afisare le-as stoca undeva gata calculate si as calcula doar saptamana curenta, vreo 3-4 secunde in total.

Intrebarea 1: ce se preteaza suficient de bine pentru stocare locala, fara baze de date? Seriile mele de date vin fiecare din alta baza de date, care nu au nici o legatura intre ele, deci locul lor nu ar fi in nici una din ele. Ma gandesc la un CSV sau un JSON_ENCODED string scris intr-un fisier sau un XML. Scriptul care le-ar culege si le-ar pune la loc in array ar fi PHP.

Intrebarea 2: Google Charts folosest un format dubios de date numit DataTable, dar merge si cu un simplu array multi-dimensional. Pe moment folosesc un array multi-dimensional, are rost sa ma incurc cu complexitatea unui DataTable? Pe moment pana si matricea asta am de gand sa o scriu un pic ciobaneste, gen PHP scoate ca output matricea ca text: echo "
var data = google.visualization.arrayToDataTable([
['Week','IS','SIS','IS&U'],
['19',0,0,3214],
" etc, cu seria de date intr-un foreach. Nu e elegant, dar e foarte eficient si imi e o lene cumplita in a face ceva mai elegant, dar mai complicat.

Intrebarea 3: Am omis ceva?
 
1. Cel mai simplu pare json_encoded, că îți iei frumos obiectul și îl scrii/citești imediat, iar parsarea e relativ cunoscută (json nu e chiar complet definit, dar e mai bine decât csv). Doar că trebuie să fii atent la updates și concurență (chiar dacă scrierea ar trebui să fie rapidă), presupun că vei vrea un backup al chestiei dacă durează prea mult query-ul pentru re-generearea datelor. La așa ceva se pretează un object cache (redis/memcached), dar introduce prea mare complexitate dacă e folosit doar acolo.

2. Nu. DataTable-ul e necesar dacă vrei să faci chestii complexe (gen animații spectaculoase când adaugi un datapoint nou, scrolling și alte bălării - dacă ai folosi de fiecare dată arrayToDataTable ți-ar reface tot chart-ul și n-ar arăta frumos), dar cât timp nu vrei de-astea, array e super ok.

3. Întotdeauna, dar îți vei da seama mai încolo :biggrin:.
 
Multumesc, tocmai voiam sa scriu ca am terminat deja folosind json_encode. Inca mai am dubii daca sa fac actualizarea o data pe zi in afara orelor de program sau o data pe saptamana (cand se actualizeaza datele pentru una din serii) si real-time pentru cele care chiar sunt real-time. Din motive de lene (de fapt, de performanta a paginii) inclin sa o fac zilnic, intr-un scheduled task (server Windows).
 
Alta intrebare, fara legatura cu HTML-ul, ci cu SQL: pe acelasi server, aceeasi tabela, aceste doua queries ruleaza in timpi extrem de diferiti, ma-sa stie de ce. Primul ia 30 se secunde, al doilea 1 secunda, avand index pe RequestDate si o tabela de 3.5 milioane inregistrari.

SELECT COUNT(DISTINCT Username) AS TheUsers FROM dbo.[AP-Data] WHERE datepart(year,RequestDate) = 2017 AND datepart(month,RequestDate) = 3

SELECT COUNT(DISTINCT Username) AS TheUsers FROM dbo.[AP-Data] WHERE datepart(year,RequestDate) = 2017 AND datepart(week,RequestDate) = 11

Practic primul numara utilizatorii de luna asta, al doilea de saptamana asta; primul face full table scan (din execution plan), al doilea index lookup.

LE: SELECT COUNT(DISTINCT Username) AS TheUsers FROM dbo.[AP-Data] WHERE RequestDate > '2017-03-01' e executat intr-o secunda, pe index.

SELECT COUNT(DISTINCT Username) AS TheUsers FROM dbo.[AP-Data] WHERE RequestDate > CONCAT(datepart(year,getdate()),'-0',datepart(month,getdate()),'-01') e executat in 30 de secunde. Acel CONCAT are ca rezultat fix '2017-03-01'.
 
Last edited:
Nu știu cum face efectiv SQL server calculul de cost, nu prea am lucrat cu el, dar cam așa e teoria de DB.

Astea-s de obicei probleme de estimare a costului de execuție, și în multe cazuri nu se descurcă atunci când parte din condițiile care, pentru tine, sunt clar fixe (ex: concat-ul de dată), sunt rezultat al unei funcții, fie ea și deterministă. Pentru că estimatorul intră înainte de a fi fost executat absolut nimic, și se pierde în funcții complexe. Dacă nu ai field = :input începe distracția: e function(field) = :input? Avem un function-based index pe field cu funcția aia? Putem mânări ceva din celelalte condiții? Dacă nu, full table scan. E field = function( :input)? Păi eu de unde să știu ce face function( :input)? Că funcția va fi executată pe fiecare rând.

Estimările depind inclusiv de parametrul dat. Ex: poți avea surpriza ca datepart(week, requestdate) = 5 să fie full table scan și datepart(weeek, requestdate) = 11 să fie index lookup, atunci când ai o histogramă pe coloană sau index și DB-ul zice "păi 90% din index e cu = 5, n-are rost să mă mai chinui cu el, fac full scan"; chestia e că dacă DB-ul are o părere mult mai bună despre storage decât e de fapt (în estimare are IOPS grămadă, dar practic e un HDD obosit), atunci full scan-ul o să țină mai mult decât utilizarea indexului. În Oracle ai parametri de configurare ai estimatorului, astfel încât să-l îndrepți pe calea cea bună, nu știu de SQL server.

Versiunea corectă index-based simplu pentru select-ul de mai sus e RequestDate BETWEEN '2017-03-01 00:00:00' AND '2017-03-01 23:59:59' - da, calculate de tine manual în afara DB, nu ca rezultat al unei funcții din SQL. Asta e, o fi SQL Turing-complet dar asta nu înseamnă că e optim :smile:.

BTW, tu sigur n-ai un function-based index cu datepart(week, RequestDate) pe undeva? Pentru că nu credeam că e SQL server chiar atât de deștept încât să folosească un function index atunci când nu există explicit - dar poate e o excepție la câmpuri DateTime - dubios, că un astfel de feature umflă dimensiunea indexului destul de mult.
 
Last edited:
Sigur nu am nici un index de care sa nu stiu si de care sa nu fi pomenit, nu mai are nimeni acces la baza aia de date (si la tot serverul, de fapt).

Am descoperit ca in unele cazuri WHERE functioneaza indexat cu valori si uneori nu, dar aproape niciodata cu functii pe coloana din conditie.

De pilda, WHERE RequestDate >= dateadd(month, datediff(month, 0, getdate()), 0) merge indexat, WHERE RequestDate < dateadd(month, datediff(month, 0, getdate())+1, 0) merge, dar WHERE dateadd(month, datediff(month, 0, getdate())-1, 0) nu merge indexat. Cea mai probabila cauza e ca se uita sa vada cate inregistrari indeplinesc conditia (in index) si daca sunt multe calculeaza ca e mai eficient sa faca table scan decat zeci de mii de SEEK pe row.

In schimb, WHERE DATEPART(month, RequestDate) nu va folosi aproape niciodata index. Nu stiu de ce, ca WHERE DATEPART(week, RequestDate) o face, o fi o optimizare manuala facuta de Microsoft in datepart(week) presupunand ca intr-o saptamana volumul de date e mai mic decat intr-o luna si undeva intre zi si an tot trebuiau sa traga o linie.
 
Nu cred că sunt optimizări manuale, mai degrabă analize pe index. E ceva legat de reprezentarea internă a tipului de dată, dar probabil trebuie citit destul de mult ca să-ți dai seama exact ce se întâmplă acolo :frown:.

Strict pentru SQL-ul tău de sus, un index compus (dată, username) s-ar putea să ajute, pentru că în condițiile astea rezultatul select-ului poate fi aflat direct din datele din index și nici nu mai trebuie să facă seek pe row.
 
Putem muta offtopicul cu SQL in topicul cu SQL? Multumesc.

Am o pagina HTML cu un antet, un tabel lung si un subsol lung. Tabelul contine butoane care care fac POST catre aceeasi pagina. Cand utilizatorul apasa unul din butoanele alea, pagina se reincarca cu scroll-ul in capul paginii.
Caut o metoda de a face autoscroll la acceasi pozitie unde se afla utilizatorul inainte de apasarea butonului.

Stiu ca exista JSON si se poate elimina refresh-ul. Nu doresc. N-am timp sa invat JSON/DHTML/etc. acum.
Stiu ca se poate face autoscroll catre un anumit element din pagina si acela poate fi butonul apasat, dar acest tip de autoscroll nu aduce pagina FIX la pozitia initiala, ci doar aduce acel element pe ecran. Ma intereseaza un autoscroll cu precizie de pixel. De ce? Pentru ca tabelul este deosebit de repetitiv si oboseala cautarii randului unde ma aflam este enorma.
As mai vrea ca scroll-ul sa fie tip "salt", nu cu animatie, sa se afiseze direct acea pozitie, astfel incat sa nu pierd randul de sub ochi.
 
Păi iei scrollTop înainte de refresh (îl pui în parametrii POST/GET) și îl setezi în noua pagină, după ce s-a randat toată pagina (altfel tot vei avea diferențe).
 
Detalii, ca n-am mai facut.
Fac JS care sa fie rulat la apasarea butonului de submit si acel JS sa completeaze valoarea unui input cu scrollTop de la <body>? Dar butonul o sa mai functioneze ca submit?
 
Ai event de onSubmit pe form. Iar la încărcare testează onLoad, dar nu-s sigur că e event-ul care trebuie (vezi și onpageshow).
 
Back
Top