Jump to content
php.lv forumi

Roze

Administratori
  • Posts

    1,561
  • Joined

  • Last visited

Everything posted by Roze

  1. Principā Kavacky teiktais ir tuvāk patiesībai .. koderiem ar laiku apnīk uzturēt vecas lietas un tad vienkāršāk ir sākt jaunu. Nu kaut vai, piemēram, ja palasa to mysql ekstensijas deprecation iemeslus https://wiki.php.net/rfc/mysql_deprecation : Kas patiesībā nemaz tā nav, jo http://lv.php.net/manual/en/mysqlnd.overview.php var skaidri un gaiši izlasīt: As of PHP 5.3.2 MySQL Native Driver supports the compressed client server protocol. Extensions such as ext/mysql, ext/mysqli, that are configured to use MySQL Native Driver, can also take advantage of this feature. Smieklīgākais, ka piemēram PDO izkrīt .. .. tāpat - MySQL Native Driver has supported SSL since PHP version 5.3.3 Par prepared statementiem var strīdēties - jā var teikt, ka tā varbūt ir drošāk (mazāka inject iespēja nekorekti apstrādātiem mainīgajiem) taču 99% gadījumu weblapām prepared statementi ir diezgan nejedzīgs pasākums, jo brīdī, kad php atslēdzas no db (kas parasti notiek katra pieprasījuma beigās) DB serveris par visiem prepared statementiem aizmirst .. attiecīgi praksē izveidot vienu prepared statementu un tad to izpildīt ir ar kārtu laikietilpīgāk un resursprasīgāk. Galugalā atliek tikai citēt tajā pašā RFC rakstītot "The extension is not broken. The problem is the bad usage. It can be used safely, and good developers have been doing so for ages, by creating php wrappers." Ekstensija droši vien vienkārši nonāks PECL repositorijā un vairāk nekas nemainīsies..
  2. Nu kā uz to skatās, ir reizēm diezgan smieklīgi, ka programmētājs kurbulē frameworku ar 10k rindiņām, lai pieslēgtos pie DB un izpildītu 1-nu kveriju, jo savādāk neprot vai vienkārši nespēj paskaidrot kā un kas vispār notiek :) Mācību (sākotnējā) procesā personīgi šķiet, ka no visādiem frameworkiem labāk turēties pa zināmu distanci ..
  3. mysqli_ neskaitās "vecā stila". .. bez tam ko tad _Frameworks_ citu izmanto? p.s. ja vispārīgi, tad nav arī nekāda liela starpība izmantot mysql_* (izņemot to, ka lai nekristu uz nerviem "jaizoperē" (php sourcē 1 rinda) vai jāignorē NOTICE par deprecated pie connecta), jo lielākoties parasti visas PHP instalācijas ir uzliktas un tāpat strādā caur MYSQLND (MySQL Native Driver), līdz ar to nav būtiska starpība vai mysql/mysqli vai piemēram PDO.
  4. Nedaudz saistībā par tēmu .. Pirms kāda laika PHP dev listē bija cepiens (saistībā par debugera phpng iekļaušanu vai neiekļaušanu corē) un tad daži cilvēki diskusijas ietvaros iespringa uz to, ka php zaudē savu popularitāti un lai arī aplikāciju izplatība ir liela, parāk maza uzmanība ir pievērsta developeriem un viņu vajadzībām/tooļiem, pārāk inerti un lēni ieviestas nepieciešamās fīčas (pilns 64bit int / utf8 u.c. supports) utt: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html http://www.tiobe.com/index.php/content/paperinfo/tpci/PHP.html
  5. Jautājums/problēma ir gana interesants, taču grūti komentēt, ja nav zināmi visi apstākļi, jo pēc "random datus no datubāzes bez atkārtošanās kamēr nav apskatīti visi rezūltāti. Laikam vajadzētu to darīt ar sesijām, katru parādīto rezūltātu ielikt sesijā" nav skaidrs kāds ir datu apjoms 'answer' tabulā, vai "bez atkārtošanās" nozīmē katram lapas apmeklētājam individuāli vai arī vienkārši jebkurš ieraksts kam status ir 1 (var atkārtoties vienlaicīgi diviem un vairāk lietotājiem) utt. Vispārīgam domu gājienam un idejām var palasīt piemēram http://jan.kneschke.de/projects/mysql/order-by-rand/ raksts gan pavecs (2007), bet, manuprāt, aizvien aktuāls gan no risinājuma, gan pašas problēmas viedokļa .. Pēc 1-2 gadiem (ja dati aug (nedod dies ar eksponenciālu ātrumu)), tad "cisterna" ir abos variantos - gan "kopējot" visus datus pa tīklu, gan arī pēc RAND() orderējot miljards ierakstus (lai atlasītu 1) .. atšķīrība ir tikai vai matus plēš DBA vai tīkla administrators (vai abi) :) Ja tā answers tabula ir maza (izskatās pēc kaut kādas aptaujas) - nu, teiksim, līdz 1000 ierakstiem, tad patiesībā Леший, variants/komentārs par to, ka ātrāk būs selectēt visus datus un aplikācijā randomizēt ir diezgan pareizs, jo MySQLs nu gaužām slikti izpildās ar ORDER BY RAND(), proti, parasts izpildes scenārijs būs: mysql> explain select * from table order by rand() limit 1; +----+-------------+---------------------------+------+---------------+------+---------+------+------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------------------------+------+---------------+------+---------+------+------+---------------------------------+ | 1 | SIMPLE | table | ALL | NULL | NULL | NULL | NULL | 394 | Using temporary; Using filesort | +----+-------------+---------------------------+------+---------------+------+---------+------+------+---------------------------------+ Un temporary ir "source of evil", protams, maza apjoma datiem MySQLs to tabulu var iebakstīt RAMā (tmp_table_size šķiet noklusēti 30Mb) un tad tas varbūt no lietotāja/programmētāja viedokļa nav īpaši manāms, bet, ja tas sāk pārsniegt, šo limitu, tad dati tiek "kopēti" uz temporāru diska tabulu un tad sākas dieva zīmes .. Par performances atšķirībām var izlasīt arī iepriekš minētajā rakstā - "As you can see the plain ORDER BY RAND() is already behind the optimized query at only 100 rows in the table." (pieņemu gan, ka, laikam ejot (uz jaunākām MySQL versijām), rezultāti varētu būt labāki arī ar visu tmp tabulu). Attiecīgi F3llony minētais " RAND() * MAX(ID)" varētu būt tuvāka patiesībai, lai gan atsevišķos variantos anyway būs ir dažādi vipendroni, proti: SELECT * FROM answers WHERE id = CEIL(RAND() * (SELECT MAX(id) FROM answers)) .. jēdzīgi strādā tikai tad, ja tabula ir monotoni augoša un nav nekādu pārtraukumu t.i. nav dzēstu ierakstu vai piemēram ierakstu, kas neatbilst vajadzīgajiem (šajā gadījuma tie kas status != 1). To var itkā risināt šādi: SELECT * FROM answers WHERE id >= RAND() * (SELECT MAX(id) FROM answers) AND status = 1 LIMIT 1; taču šeit ar var gadīties ka, ja nejauši randomizētā id vērtība piemēram ~sakrīt ar maksimālo tabulas ID, taču tam ir kāds cits status kā 1, tad netiks atrasts neviens ieraksts: Sanāk, ka būtu jaselectē arī tos ierakstus, kuri var būt id <= [mūsu rand] un tad no abiem ierakstiem jāņem 1: SELECT * FROM ( (SELECT * FROM answers WHERE id >= RAND() * (SELECT MAX(id) FROM answers) AND status = 1 LIMIT 1) UNION (SELECT * FROM answers WHERE id <= RAND() * (SELECT MAX(id) FROM answers) AND status = 1 LIMIT 1) ) AS t LIMIT 1; var protams atmest ārējo SELECtu un fetchot tikai 1 rowu no aplikācijas, tāpat arī ja kādā veidā ir zināms MAX(id) random daļu aizstāt ar reālu vērtību no aplikācijas: Ja ar php pseidokodu $id = random(1, 324234); iegūstam vērtību 1234, tad DB serverim kveriji izskatīsies apmēram šādi: (SELECT * FROM answers WHERE id >= 1234 AND status = 1 LIMIT 1) UNION (SELECT * FROM answers WHERE id <= 1234 AND status = 1 LIMIT 1); un MySQL pat varēs atsevišķos gadījumos izmantot savu Query cache, kas nav iespējams RAND() kverijiem. Cik skatījos uz palielām tabulām (500m - 1bn ierakstu) izpildās 0.0x laikos .. ātrdarbībai protams būtu vēlams kombinēts indekss uz status+id .. .. .. bik sanāca palags.
  6. draugiem.lv faktiski neko (ja neskaita Zend Opcache, kas ir tikai php opcoda kešošanai) nekešo t.i. nav nekāda html keša (arī datu keši ir visai nosacīti t.i. ja tādi ir tie ir servisu pusē un php par to neko nezin) attiecīgi tās 20ms ir tas ko patērē php izpildoties no lapas sākuma līdz beigām, bet kā jau rakstīju tas ir vidējais pieprasījuma izpildes laiks, Loģiski, ka ir portāla sadaļas, kas droši vien ģenerējas 1ms un ir kas 1000ms. Vēl protams arī būtiski, kas tajās 180ms ietilpst t.i. svarīgi vai tās 180ms ir domātās viss sākot ar konektu un līdz pieprasījuma beigām (t.i. arī dns lookups / tcp connects / SSL handsheiks, kas reizēm aizņem būtisku laika daļu) vai tiešām tikai laiks pēc konekta līdz ~pēdējam (html) baitam.
  7. Kāpec neiet? kvalitatīvi+lēti - nebūs ātri (piemērs var būt opensource projekti, kas var developēties gadiem var patērēt daudz cilvēkstundu/resursu, taču rezultāti (bieži) ir diezgan labi/kvalitatīvi (labāki par par komerciāliem risinājumiem) un gala lietotājs par to principā nemaksā) kvalitatīvi+ātri - lielākoties noteikti nebūs lēti (protams arī aklai vistai grauds gadās) .. Var piekrist, ja viss ir no nulles, taču mūsdienās reti kur var vairs izgudrot riteni t.i. vairāk vai mazāk visus risinājumus var nopirkt uzreiz/gatavus/ar minimālu pielāgošanu/maksimālām opcijām/onsite supportu utt untājoprojām. Lielie biznesi laika taupīšanas nolūkos vienkārši uzreiz nopērk visu tavu kompaniju ar visiem darbiniekiem / patentiem utt (kas notiek tālāk, cits jautājums). .. tāpēc arī ir izvēlies 2 no trim.
  8. Bet tas (atrunas par projekta lielumu, kas, manuprāt, nebija nekur norādīts) nekādi tāpat nettaisno atbildi - "Absolute bullshit.", ja vien tas nebija domāts par "pirkstu griezšanu", jo savādāk ar šādu atrunu var tikpat labi teikt, ka kamdēļ vajag kaut kādai "labi ja 1 lietotājs nedēļā" lapai, piemēram, formu mainīgo pārbaudi utt .. iespēja, ka "sūds trāpīs ventilatorā" tomēr pastāv. Līdz ar to tādi 100% apgalvojumi nav īsti korekti (imho) t.i. labāk ir piedāvāt dažādus/vairākus risinājumus ar saviem plusiem un mīnusiem (ātri, lēti, kvalitatīvi - 2 no 3) un tad lai katrs pats izsver un izvēlas (foruma būtība) :)
  9. Pirms ņemties ar tehnoloģijām ieteiktu tomēr kaut ko pamonitorēt (ja tas, protams, nav darīts, lai gan pārlasot postus tā nešķiet), jo "900ms uz 150ms" (vismaz man) neko neizsaka .. Kur 750 ms tika iegūtas? Kur tās 150ms tiek pātērētas? Kas aizņem visvairāk laika? Varu ieteikt http://newrelic.com/application-monitoring, kas piedāvā ļoti uzskatāmu aplikācijas darbības statistiku un analīzi (php, python, java, ruby, node, net utt). Bezmaksas versija ir ar 24h darbības reportu ar ko pilnībā pietiek. Kā piemēru varu minēt - piemēram, draugiem backenda (t.i. php/db u.c. network servisi) average izpildes laiks ir 20 ms tai pat laikā faktiski lapa renderējas (lietotājam parādās) average vismaz 2+ sekundes. Var jau skaldīt matus un kaut kur vēl iegūt 1,2-10 .. ms, taču tas jau nekādi nemaina faktu, ka klienta galā ir "bloatware" un ņemšanās ap backendu uz kopējā fona nebūs pat 1% ieguvums. Un šeit ir tā vieta kur palīdz kaut kādas kopainas redzēšana t.i. reizēm atliek tikai nomainīt vienu komponenti, koda gabalu, sql kveriju u.t.t un viss notiek ..
  10. Jautrības labad.. Lielākajai daļai piesaukto (storage) risinājumu šādā vai tādā veidā ir pieejams (ja gribās svešvārdu terminus - Posix compliant) failsistēmas interfeiss, piemēram, S3 - s3fs, mysql - mysqlfs, mongodb/gridfs-fuse u.t.t. Līdz ar to "mkdir() bullshits" kodā var būt viens un tas pats, taču aplikācijai/php kodam transparenti rezultēties pavisam dažādos izpildījumos.. Attiecīgi nebūt nav obligāti jākodē (vai jāparedz) kaut kādi N dažādi backendi vai koda blāķi kāda specifiskam (piemēram ko darīt, ja vairs nav vēlme maksāt par S3, bet kods pilns ar "stumšanu uz bucketiem") variantam. Tāpat arī ar CDN (ja protams ar to nav domāts būvēt kaut kādus savus vipendronus), tad mūsdienās visi CDN pakalpojumu sniedzēji (Cloudflare, Akamai, Limelight utt) vairāk vai mazāk piedāvā transparentu sava produkta izmantošanu un aplikācijai nekas nav jāmaina vai papildus jākodē (<flameon> jo programmētāji ir dārgāki (un darba rezultāti vairāk neparedzami) nekā viens sistēmas administrators</flameoff>). Par šo atbildi gan nedaudz brīnos, proti, ja ir iespēja nodalīt statiskos (lietotāju uploadētu saturu), tad to, manuprāt, noteikti vajag darīt. Ir bijuši pietiekami daudz gadījumu/piemēru, kad nekorektu (vai pat ar standarta noklusēto ( https://bugzilla.redhat.com/show_bug.cgi?id=885839)) konfigurāciju webserveri piemēram ļauj izpildīt (pietam "validā") .jpg failā esošu php kodu utt. Protams, ar pienācīgu apstrādi var no visa kā izvairīties, bet nu ..
  11. Nu mysqls jau faktiski arī mēģina kaut ko darīt lietas labad (un ja ierakstu nav daudz, tad viss notiek (samērā) ātri) - proti veido to starptabulu, bet: 1. Tās starptabulas veidojas uz katru pieprasījumu 2. Atkarībā no datu apjomiem temporārās tabulas var sākt rakstīties no atmiņas uz disku ( http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_tmp_table_size ) - tad paliek pavisam slikti. Pēc pieredzes tabulām, kur ierakstu skaits sākt pārsniegt pārsimt tūkstošus pilnībā mēģinu izvairīties no GROUP BY, COUNT(*), ORDER pēc lauka (ja pieprasījumu neapmierina kāds indeks pilnībā).
  12. Ja datu ir daudz un kverijam jāizpildās kaut cik pārskatāmā laikā (pieņemsim standarta 1-2 sec max lapas ielādei), tad faktiski ir jāatmet doma par datu kārtošanu pēc neeindeksētiem un vēl jo vairāk temporāriem laukiem. Starptabula ar sarēķinātiem varētu būt jēdzīgākais variants.
  13. Var mēģināt lietot UCS-2 tābles/lauka kodējumu? http://msdn.microsoft.com/en-us/library/bb330962(SQL.90).aspx#intlftrql2005_topic2
  14. php GD ir kādas 2-3x (ja ne vēl) atrāks par IM .. nemaz nerunājot ja vienlaicīgi jaresaizo vairākas bildes tad Magicks un kaste atpūšas vispār. Kaut kāds fiksais kods no arhīviem: function thumb($source, $dest, $w = 0, $h = 0) { $size = getimagesize($source); if ($w && $size[0] > $w) { $ratio = $size[0] / $w; } elseif($h && $size[1] > $h) { $ratio = $size[1] / $h; } $ratio = max($ratio, 1.0); $w = (int)($size[0] / $ratio); $h = (int)($size[1] / $ratio); if($w && $h) { $resize = imagecreatetruecolor($w, $h); if($size[2] == 2) { $img = imagecreatefromjpeg($source); imagecopyresampled($resize, $img, 0, 0, 0, 0, $w, $h, $size[0], $size[1]); imagejpeg($resize, $dest,95); } elseif($size[2] == 1) { $img = imagecreatefromgif($source); imagecopyresampled($resize, $img, 0, 0, 0, 0, $w, $h, $size[0], $size[1]); imagegif($resize, $dest); } elseif($size[2] == 3) { $img = imagecreatefrompng($source); imagecopyresampled($resize, $img, 0, 0, 0, 0, $w, $h, $size[0], $size[1]); imagepng($resize, $dest); } imagedestroy($img); return filesize($dest); } else { return 0; } } Lietojums apmēram šāds (atgriež thumbnaila faila izmēru vai 0): <? thumb('vecabilde.jpg','thumbnails.jpg',[opcionaals_max_platums],[opcionaals_max_augstums]); ?> Primārais tiek ņemts vērā platums (var sakombinēt kā vajag proti ņemt vērā mazāko izmēru utt).
  15. Drošvien nepalīdz konkrētajā situācijā (iesācējam), bet ideja kapēc kaut kādu gatavu skriptu (it īpaši ja nav jausmas ko tie vispār dara) izmantošana ne vienmēr ir optimāla. Visa tā ķeska pāris rindās ( http://lv.php.net/glob ): <? foreach (glob("*.mp3") as $filename) { echo $filename."\n"; } ?>
  16. Roze

    Cron jobs

    Diezgan jocīgi ka 5 min dati ir atkarīgi no 30min skripta datiem - loģiski itkā sanāktu otrādi jo kapēc tad vispār darbināt to 5min skriptu ja jau 'sarežģītais' crons griežas krietni retāk. Parasti gan tipiskā problēma ir tajā momentā kad cronjoba, kas iešedulēts ik pa 5min, izpildes laiks paliek lielāks nekā 5min (t.i. intervāls kurā crons tiek darbināts) attiecīgi tākā pašam cronam ir vienalga tad viss beidzas ar to ka uz kastes griežas 100 procesi kas visi mēģina darīt vienu un to pašu. Prātā nāk divi varianti: 1. Taisīt statusa failus kuros ierakstīt vai konkrētais skripts var darboties vai nē un tad skripta sākumā checkot to: teiksim 30min skriptā 30min.php: <? file_put_contents('is_30_minscript_running',1); // tavs kods file_put_contents('is_30_minscript_running',0); ?> Bet 5min skriptā: <? if(file_get_contents('is_30_minscript_running')) { die('30min script still running!'); } // tavs kods ?> Mīnus šim ir ja lielais skripts kautkādā brīdī nogāžas (fatal error) tad pēdējais statuss paliek nekorekts un sīkais 5min skripts vismaz 30min nedarbojas.. (var arī vienkārši checkot vai griežas konkrēts process teiksim iekš 5min skripta sākumā ielikt kaut ko tādu kā: <? if(`ps aux | grep [3]0minskripts.php`) { die('30min script still running!'); } // grepam japadod regulara ekspresija lai vinsh nenogrepo pats sevi no processlistes // tavs kods ?> 2. Otrs variants ir uzrakstīt piem bash scriptu kas darbojas permanenti ar while loopu un sleep. Tīri teorētisks piemērs #!/bin/bash while [ 1 ]; do php 5min.php sleep 300 php 5min.php sleep 300 php 5min.php sleep 300 php 5min.php sleep 300 php 5min.php sleep 300 php 5min.php php 30min.php done
  17. Ganjauka ir definēts include_pathos .. Ir ja tu skriptā vēlies darīt citas darbības ka nav saistītas ar php (while / sleep (ar php sleepot ir besis) etc).. Minētais piemērs var būt tikai vienas rindiņas izrāvus.. .. bet nu problem solved..
  18. Pamēģini palabot to contrab scriptu kaut kā šādi #!/bin/sh /opt/apache/php/bin/php -d display_errors=1 /utils/script.php >> /utils/log.log -d display_errors=1 <- opctionāli ja uz webservera ir izslēgts erroru rādīšana Šādi tev skripts outputu iemetīs logfailā un varēsi saprast kas par problēmu... Visbiežāk ar crontabu ir tā ka crontabs nedefinē CWD (current working directory) līdz ar to php skriptu kas kaut ko includo no relatīviem pathiem neizpildās.. Ir protams arī interesanti gadijumi (piemēram Oracle utt) kur crontab skriptam speciāli jādefinē dažādi ENV variabļi (kas noklusēti nāk no konsoles lietotāja kad komanda tiek izpildīta shellā bet crontabam nav)..
  19. Izsktās ka win PECLs ir down.. var mēģināt šo - http://dllcentral.com/php_apc.dll/5.2.5.5/
  20. Šādu informāciju var sniegt tikai pēc policijas vai citu tiesīgu struktūrvienību, kurām ir attiecīga sankcija, pieprasījuma.. Meklēt kādu administratoru ir bezjēdzīgi, jo par to draud kriminālatbildība..
  21. Roze

    Atkal SMS

    SMS pēc būtības nearko neatšķiras no citiem maksājuma veidiem - kredītkarte / cash / pārskaitījums / whatever... Kapēc lai pēkšņi uz vienu no maksājuma veidiem būtu kaut kādi izņēmumi?
  22. Ja nemaldos glob() http://lv.php.net/glob to dara automātiski <? $faili = glob("/direktorija"); // faili kas sākas tikai ar 'a' $faili = glob("/direktorija/a*"); ?>
  23. Roze

    video faili

    Vienkāršākais risinājums manuprāt izmantot 'Sendfile' iespējas, proti pirms faila downloada pārbaude notiek caur PHP un tad php padod konkrētu failu (protams to var uztaisīt pilnībā ar php bet tas ir diezgan lēndarbīgi). Ja kā webserveris izmantojas Apache: http://tn123.ath.cx/mod_xsendfile/ http://blog.adaniels.nl/articles/how-i-php-x-sendfile/ Daļai citu serveru šī fīča jau ir iebūvēta..
  24. To tev neviens nepateiks jo tas atkarīgs no katra gadijuma atsevišķi. Ja izvelk divus vispārīgus gadijumus tad ar PHP ātrāk varētu būt ja pie lielas tabulas joino mazu tabulu. Teiksim ir tabula 'ieraksti' kurā ir id | kategorijas_id un tabula 'kategorijas' kurā ir kategorijas_id | kategorijas_nosaukums. Tagad ja tu selectētu visus ierakstus (teiksim miljons) un joinotu klāt kategoriju lai dabūtu kategorijas nosaukumu sanāktu ka tu miljons reižu selectētu varbūt kādus 10 dažādus kategoriju nosaukumus.. Pretēji tam lai vienkārši ar PHP noselectētu tos 10 ierakstus no kategorijām, saliktu masīvā un izvadītu pie konkrētajiem ierakstiem. Ar php nav iespējams ja JOINs notiek starp divām lielām tabulām.. (proti lai nolasītu vienu tabulu sanāktu patērēt daudz resursu) Tad tīri SQL ir labāk.
×
×
  • Create New...