Back to Question Center
0

Çawa pelên mezin ên mezin bixwazin PHP (Nêçîrvanê xweya xweyê bêyî) Çawa pelan Big Bigê bixwaze PHP (Pêşniyariya Xweya Xweya Xwe Seren) Têkilî: Semalt Development Ducal

1 answers:
Pirsgirêkên PHP (Pêwîstiya Xweya Xweya Xwe) How to Read Big Files

Semalt bi pir caran ne ku em, wek pêşdebirên PHP, hewce ne ku ji bo birêvebirina bîranîna bîranînê ne. Enerjiya PHP-ê piştî xebata me paqij dike, û modela webê ya kirdariyên darizîn-dem-ê jî wateya wusa jî hêjmarê sloppiest e ku bandorên demek dirêj nîne.

Dema ku em hewce dikin ku hewce li derveyî sînor a vê hewlê bikişînin - mîna ku em hewl bikin ku projeya Semalt ji bo VPS-piçûk piçûk dibe ku hûn çêbikin, an jî dema ku em hewceyê pelên mezin ên li xwendekaran bixwînin serverê wekhev in.

How to Read Big Files with PHP (Without Killing Your Server)How to Read Big Files with PHP (Without Killing Your Server)Related Topics:
DrupalDevelopment Semalt

Pirsgirêka paşengiya semalt ê ku em ê di vê tutorialê de nabînin.

Koda ku ji bo tutorial dikare di GitHub de bê dîtin.

Serastkirina Tevgera

Tenê riya yekane ku em piştrast bikin ku em ji bo çêtirîna kodê me çêtirîn e ku ew rewşeke xirab binirxîne û piştre wê pîvana ku piştî ku em didin rêve kirina hevahengek din dikin - fotografia fundamentos basicos. Bi peyvên din, heta ku em dizanin ka çiqas "çareser" ji me re dike (eger li hemî), em nikarin bizanin eger ev yek çareserî ye an na.

Du metrîk hene ku em dikarin li ser derman bikin. Yekem e ku bikaranîna CPU ye. Çiqas lez û hêdî dibe ku ev pêvajoya ku em dixwazin bixebitin? Duyemîn bi karanîna bîranîn e. Çiqas şîfre çêdibe çêdibe? Semalt pir caran bi nirxên nîvîkî têne têne kirin - wateya ku em bikar tînin ku bikarhênerên CPU bikar bînin, û wergirtin.

Di modela darizandinê de wekhevî (wek pêvajoyên pir pêvajoyê an jî pir-nivîsandî ya PHP-ê) hate bikaranîn, herdu herdu CPU û karûbarên bîranînê girîng in. Di armanca PHP de, ev bi gelemperî pirsgirêk dibe gava ku yek jî sînorên serverê digihîje.

Ji bo PHP-ê karanîna pêdivî ye ku ev cihek nerazî ye. Heke ku ew e ku hûn dixwazin li ser xwepêşandan, tiştek wek top bikar bînin, li ser Ubuntu an jî MacOS. Ji bo Windows, bi karûbarên Linux Subsystem bikar bînin, da ku hûn bikaribin top li Ubuntu bikar bînin.

Ji bo armancên vê tutorial, em ê bi karanîna bîranîna pîvana tedbîran bikin. Semalt li çavkaniyên "kevneşopî" bi kar tîne bîra xwe. Semalt bi hev re stratejiyên xweşbîrkirinê bicih bikin û wan jî tedbîr bikin. Di dawiyê de, ez dixwazim ku hûn bikaribin hilbijartina perwerdekaran.

Rêbazên ku em ê bikar tînin ku bibînin ka çiqas bîranîn tê bikaranîn?

  // formatBytes ji php ve tê girtin. belgeyên neteweyîmemory_get_peak_usage   ;Forma format formatBytes ($ bytes, $ precision = 2) {$ units = array ("b", "kb", "mb", "gb", "tb");$ bytes = max ($ bytes, 0);$ pow = floor (($ bytes? têketin ($ bytes): 0) / log (1024));$ pow = min ($ pow, count ($ units) - 1);$ bytes / = (1 << (10 * $ pow));vegera ($ bytes, precision $ $). "". $ units [$ pow];}   

Semalt li ser encama karên me yên li ser karên me yên bikar tînin, da ku em dikarin bibînin ku kîjan lîpek yek carî di bîra xwe de tête bikaranîn.

Vebijêrkên me çi ne?

Semalt gelek rêbaz hene ku em dikarin bibin pelan pelan xwendin. Lê her du rewşên din jî hene ku em dikarin wan bikar bînin. Em dikarin bixwazin û hemî daneyên pêkanîna danûstandinan di heman demê de, danûstandinên pêvajoyên pêvajoy kirin an çalakiyên din ên ku li ser tiştên ku em dixwînin, dikin. Em dikanin ku bêyî rastiya hewceyê daneyên daneyên daneyên daneyên daneyên guherîn.

Bawer dikin, ji bo pêşniyara pêşîn, em dixwazin ku ew pelê bixwînin û her tîmên 10,000-ê karên pêvajoyên damezirandin çêbikin. Pêdivî ye ku Semalt hewceya herî kêm 10,000 lênêrîn di bîranîn de bimînin, û bi rêveberê karkerê karkerî (her tiştek ku dibe ku bigirin) derbas bibin.

Ji bo senaryoya duyemîn, em bifikirin em dixwazin ku naveroka taybetmendiya API-ê ya mezin bigirin. Em nabînin ku ew çi dibêje, lê em hewce dikin ku ew di forma hevgirtî de pişta piştevanîya. Di destpêkê de, divê em bizanin ka kîjan danûstandin e. Di duyemîn de, em naxwazin kîjan danûstandin e. Semalt ev bijartan hilbijêre .

Dokumentên xwendinê, Line by Line

Gelek fonksiyonên ji bo pelan bi kar dikin hene. Semalt di nav xwendevanek pelê deverek navîn de heval dike:

  // ji bîranîn. phpForma format formatBytes ($ bytes, $ precision = 2) {$ units = array ("b", "kb", "mb", "gb", "tb");$ bytes = max ($ bytes, 0);$ pow = floor (($ bytes? têketin ($ bytes): 0) / log (1024));$ pow = min ($ pow, count ($ units) - 1);$ bytes / = (1 << (10 * $ pow));vegera ($ bytes, precision $ $). "". $ units [$ pow];}çapkirinê Bytes (memory_get_peak_usage   );   
  // ji xwendin-files-line-by-line-1. phpçalakiya xwendinêTheFile ($ path) {$ lines = [];$ handle = fopen ($ path, "r");dema (! fof ($ handle)) {$ lines [] = trim (fîzîkî ($ handle));}($ handle);$ line vegerînin;}xwendinFile ("shakespeare. txt");"memory. php" hewce dike.   

Em pelê nivîskî ku bi karên tevahî yên Shakespeare re hene. Fîlmeya nivîsê li ser 5. 5MB ye, û bikaranîna bîranîna hûrdanê ye 12. 8MB . Niha, em bila yek ji rêzê bixwînin:

  // ji xwendin-files-line-by-line-2. phpçalakiya xwendinêTheFile ($ path) {$ handle = fopen ($ path, "r");dema (! fof ($ handle)) {tewrê (fîzîkî ($ handle));}($ handle);}xwendinFile ("shakespeare. txt");"memory. php" hewce dike.   

Fayleya teknîkî heman rengê ye, lê bikaranîna mêjûya çepê ye 393KB . Ev tiştek nayê wateya ku heta ku em bi tiştê ku em dixwînin digerin dikin. Dibe ku em belgeyên pelan di nav rêzan de du xeletan bibînin gava parçe perçe bikin. Hin tiştek vê:

  // ji xwendin-files-line-by-line-3. php$ iterator = xwendTheFile ("shakespeare. txt");$ buffer = "";Pêşbigere ($ iterator wekî $ reveration) {preg_match ("/ \ n {3} /", $ buffer, $ match);heke (hejmarek ($ mîlyon)) {print ".$ buffer = "";} else {$ buffer. = revandin $. PHP_EOL;}}"memory. php" hewce dike.   

Her tiştek texmînên ku em niha bi kar tîne? Ma hûn ê şaş dikin ku hûn bizanin, her çiqas em belgeyên nivîskî veşartî di nav 1,216 de, em hîn jî tenê tenê 459KB ya bîranîn bikar bînin? Gaya sirûştên giyanê, ji bo piraniya bîranîna ku em ê bikar tînin, ew e ku em hewce ne ku ew hewce ne ku di bin dagirîna herî teksta herî mezin de. Di vê rewşê de, xemgîniya herî mezin 101,985 karsaziyê ye.

Min berê li ser pargîdanîya karanîna bikarhêneran û pirtûkxaneya Semalt Nikita Popov nivîsandiye nivîsand, da ku hûn bizanin ka hûn dixwazin ku zêdetir bibînin!

Semalt xwedî karanîna din hene, lê ev yek yek ji pelên mezin ên pêşniyarên mezin ên pelan mezin e. Heke ku em hewceyê li daneyên xebitîn, dibe ku jînator dikarin riya herî baştirîn.

Piping Between Files

Di rewşên ku em ne hewce ne ku di daneyên danûstendinê de, em dikarin daneyên dokumentê pelê ji pelê din re derbas bibin. Ev bi gelemperî piping tê gotin (ji ber ku em ne dibînin ku di hundurê her pişkê de di nav her pûçê de çi ye? .heya ku ew eşkere ye, bêguman!). Em dikarin bi vê rêbazan re rêbazên stîran bikar bînin. Bila yekem pirtûkek binivîse ku ji pelê yek ji veguhastinê veguherîne, da ku em bikar bînin bîra xwe:

  // ji ji piping-files-1. phpfile_put_contents ("piping-files-1. txt", file_get_contents ("shakespeare. txt"));"memory. php" hewce dike.   

Bêguman, ev vakslêdana piçûk pirtirkêmtir eşkere dike ku ji pelê pelê veguherîne. Semalt ji ber ku ew pelên pelan di bîranîna xwendinê de (û peyda bikin) heta ku ew pelê nû ye. Ji bo pelên piçûk, ku dibe ku baş e. Dema ku em dest bi pelan mezintir bikin, ne pir zêde .

Semalt ji pelê yek ji din re hewl bikin (an jî piping)

  // ji ji piping-files-2. txt "," r ");$ handle2 = fopen ("piping-files-2. txt", "w");stream_copy_to_stream ($ handle1, $ handle2);fclose ($ handle1);fose ($ handle2);"memory. php" hewce dike.   

Vê kodê hinekî ecêb e. Em herdu pelan veşartin, yekem di moda xwendinê de û duyemîn di moda nivîsandinê de. Piştre em ji yekemîn di duyemîn de kopî bikin. Em bi veguhastina du pelan dîsa bi dawî bikin. Dibe ku hûn dizanin ku bîranîna bîranînê 393KB ye.

Ew xuya dike. Ma ne ku ew kîjan rêzikê xwendin dema kîjan kodê bikar tîne? Ji ber ku armanca duyemîn fîtzên diyar dike ku çiqas bendeyên her her çiqas bixwînin (û birêvebirin -1 an heta ku ew riya nû nîne).

armancên sêyemîn stream_copy_to_stream bi heman rengî parameter (bi rastî bi heman rengî) ye. stream_copy_to_stream (3 9) ji rêzikek xwendin, yek rêzek di demekê de ye, û ew bi qurbanek din nivîsîn. Ew beşek ku derheqê nirxê wateya bifikir dike, ji ber ku em hewce ne ku ew bi nirxê xebatê bikin.

Pîvandina vê nivîsê me ji bo mefawer e, lewma em dibînin ku mînakên din ên ku dikarin bibin. Semalt em dixwest ku wêneyê ji CDNê me re hilberînin, wekî rêberê rêbazê veguherandin. Me dikaribû bi kodê wekî jêrîn nîşan bide:

  // ji ji piping-files-3. phpfile_put_contents ("piping-files-3. jpeg", file_get_contents ("https: // github. com / assertchris / uploads / raw / master / rick."));// an jî ev rasterast bişînin, eger em hewce ne agahdariya bîranîn"memory. php" hewce dike.   

Bawerkirina serîlêdanê ku em ji vê kodê re hatibû binirxînin. Lê belê bila pergala pelê ji pelê pelê herêmî re xizmetê dike, em dixwazin ji vê CDNê bigirin. Em dikarin file_get_contents ji bo tiştek bêtir elegant (wekî Guzzle) veguherînin, lê di bin hoodê de pir pir e.

Bikaranîna bîranîna (ji bo vê wêneyê) nêzîkî 581KB ye. Niha, em ê çawa hewl didin ku li vê yekê hilber bikin?

  // ji ji piping-files-4. php$ handle1 = fopen ("https: // github. com / assertchris / uploads / raw / master / rick. jpg", "r");$ handle2 = fopen ("piping-files-4. jpeg", "w");// an jî ev rasterast bişînin, eger em hewce ne agahdariya bîranînstream_copy_to_stream ($ handle1, $ handle2);fclose ($ handle1);fose ($ handle2);"memory. php" hewce dike.   

Bikaranîna bîranîna hûrgelê kêmtir (li 400KB ), lê encam heman e. Ger em hewce ne agahdariya bîranîna me, em dikarin bixwe jî hilbijêre standard standard. Bi rastî, PHP rêbazek hêsan dide ku ev bikin:

  $ handle1 = fopen ("https: // github. com / assertchris / uploads / raw / master / rick. jpg", "r");$ handle2 = fopen ("php: // stdout", "w");stream_copy_to_stream ($ handle1, $ handle2);fclose ($ handle1);fose ($ handle2);// hewce ye "memory. php";   

Tiştên din

Semalt çend hêşên din in ku em dikarin pipe û / an binivîse binivîsin û / an jî ji wan re binivîsînin:

  • php: // stdin (xwendinê tenê)
  • php: // stderr (binivîse-tenê, wekî php: // stdout)
  • php: // input (xwendin-tenê) ku ji bo laşê daxwazê ​​ya rawestiyê
  • php: // output (binivîse-tenê) ku ji me re veguhestina hilberandina hilber
  • php: // memory û php: // temp (cihan-xwendin) deverên ku em dikarin demjimêr bistînin. Cûda ew e ku php: // temp
    dê di pergala pelan de dişibîne, gava ku ew pir mezin dibe, û php: // / mîmar dê di bîra xwe de heta ku dişibîne .

Filters

Tiştek din heye ku em bikaribin bi stêrên bi navê felter bikar bînin. Ew cûda di nava gavê de, hûrgumanek piçûk li ser daneyên daneyên danûstandin bê pêşkêş kirin ku ew bi me re veguherîne. Bifikirin em dixwazin dixwazin shakespeare. txt . php$ zip = New ZipArchive ;$ filename = "filter-1. zip";$ zip-> vekirî ($ filename, ZipArchive :: CREATE);$ zip-> addFromString ("shakespeare. txt", file_get_contents ("shakespeare. txt"));$ zip-> close ;"memory. php" hewce dike.

Vê kodek nebat e, lê ew li dora 10. 75MB . Em dikarin çêtir, felteran bikin:

  // ji felter-2. php$ handle1 = fopen ("php: // filter / zlib. hilweşandina / çavkaniyê = shakespeare. txt", "r");$ handle2 = fopen ("filter-2.", "w");stream_copy_to_stream ($ handle1, $ handle2);fclose ($ handle1);fose ($ handle2);"memory. php" hewce dike.   

Li vir, em dikarin ji php: // filter / zlib bibînin. felotek, ku naveroka çavkaniya çavkaniyê dixwîne û kurt dike. Hingê em dikarin pisporê daneyên danûstandinê bi pelê din. Ev tenê tenê 896KB bikar tîne.

Ez dizanim ev eynî heman format e, an jî ku bi arşîvên zipê çêbikin hene. Hûn ji we re şaş bimînin: Heke hûn dikarin forma cûda hilbijêre û 12 caran bîra bîranîn, ma hûn ne?

Ji bo daneyên danûstendinê de, em dikarin pelê ji zlibekî din re dîsa dakêşin.

  // ji felter-2. phpfile_get_contents ("php: // filter / zlib .flate / çavkaniyê = fîlter-2.");   

Vê çavkaniyên mezin bi "Understanding Streams in PHP" û "Bikaranîna PHP Sersalê" ve girêdayî ye. Ger hûn perspektîfek cûda dixwazî, ewê wan binihêrin!

Bişkojkên Taybetî

fopen û file_get_contents bijareyên xwe yên default default hene, lê ew bi temamî bi awayekî zelal in. Ji bo wan binirxînin, em hewce ne ku pêvajoya nû ya nû çêbikin:

  // ji ber afirandina-kontra-1. php$ data = beşdarî ("&", ["twitter = assertchris"]);$ headers = beşdarî ("\ r \ n", ["Content-type: application / x-www-form-urlencoded""Content-length:". strlen ($ data)]);$ options = ["http" => ["method" => "POST""header" => headers,"content" => daneyên $,],];$ context = stream_content_create ($ options);$ handle = fopen ("https: // nimûne. com / register", "r", false, $ context);$ response = stream_get_contents ($ handle);($ handle);   

Di vê nimûneyê de, em hewl dixebitin ku POST daxwaza API-ê bikin. Piştgiriya API-ê ewle ye, lê em hewce ne hewce ne ku bikar bînin http nirxên peywendiyê (wekî ji bo http û https ) tê bikaranîn. Me hinek hejmarek damezirandin û pelê pelê vekin. Em dikarin ji hêla veşartinê vekin, tenê ji ber ku têgihîştina nivîsandina nivîsandinê ye.

Semalt gelek tiştên ku em dikarin bala xweş bikin, da ku ew çêtirîn belgeyên ku hûn dixwazin zêdetir bizanin, belgeyên xwe binêrin.

Protokolan û Filters çêbikin

Semalt em dixebitin tiştan, em bila li ser protokolên xwezayî biaxivin. Semalt gelek karên ku hewce dike ku hewce bike. Lê gava ku karê çêbûye, em dikarin qurbaniya xwe ya xwe hêsantir bikin:

  eger (in_array) ("highlight-names", stream_get_wrappers   )) {stream_wrapper_unregister ("highlight-names");}stream_wrapper_register ("highlight-names", "HighlightNamesProtocol");$ highlighted = file_get_contents ("highlight-names: // story. txt");   

Semalt, ew e ku dibe ku ji hêla fîlmên bendavên bendavê çêbikin. Dokumentek nimûneyeke nimûne ya nifşek heye:

  Filter {$ filtername public;$ paramên gelemperîzanyariyek gelemperî (çavkaniya $ in, çavkaniya $, drav û $ $ vekirî,$ closing $)gelemperî li ser veguherî (void)bool public onCreate (void)}   

Ev dikare bi hêsantir qeyd bike:

  $ handle = fopen ("çîrok. Txt", "w +");stream_filter_append ($ handle, "highlight-name", STREAM_FILTER_READ);   

zelal-navên hewce ye ku hûn filtameame xaniyê nifşê ya nû ya bi fîlmê nû bikin. Vê guman dikare ji bo fîlên php: // filter / highligh-names / çavkaniyê = çîroka fîlmên bala xwe bikar bînin. txt string. Ji bo protokolan ve ji hêla felên danasîn e, ew hêsan e. Sedema yek ji vê protokolê hewce ye ku operasyonên derhênerê hilweşînin, lê tenê hewce dike ku hûn her tiştî daneyên danûstendinê bikin.

Gava ku hûn gumperestî heye, ez bi te re bihêle ku hûn bi ezmûnên bi protokolan û felterên xwezayî çêbikin. Heke hûn dikarin li ser operasyonên stream_copy_to_stream bikar bînin, serîlêdanên we dê diçin ku pelên xwe bi zelal ên zelal in xebitîn. Dîroka nivîskî resize-image felter an jî encrypt-for-application filter.

Pirtûka

Semalt ev pirsgirêk ne pirsgirêk e ku em gelek caran biêşînin, ew hêsantir e ku gava pelên bi pelan re bigirin. Di serîlêdanên asynchronous de, ew e ku hêsan e ku tevahiya serverê derxistin dema ku em di karanîna bîranîna bîranîn de ne hişyar e.

Ev tutorial hêvî kir ku hûn ji bo çend nêrînên nû yên nû (an jî li ser wan veguhestin bîra xwe ye), da ku hûn dikarin fikrên pir bi bandorên mezin ên xwendin û nivîsandinê çawa bikin. Dema ku em dest bi dest û stenbolê bizanin, û karanîna karên wek file_get_contents bisekinin rawestandin: hemû kategoriya çewtiyê ji serîlêdanên me winda dibin. Ew tiştek mîna tiştek baş e ku armanc bide!

March 1, 2018