public function upload_part($file_handle, $part_number, $upload_url, $auth_token) {
$chunk_size = 5 * 1024 * 1024; // 5MB chunk
fseek($file_handle, ($part_number - 1) * $chunk_size);
$data = fread($file_handle, $chunk_size);
$sha1 = sha1($data);
$response = wp_remote_post($upload_url, [
'headers' => [
'Authorization' => $auth_token,
'X-Bz-Part-Number' => $part_number,
'X-Bz-Content-Sha1' => $sha1,
'Content-Type' => 'application/octet-stream'
],
'body' => $data,
'timeout' => 120
]);
return $response;
}Salutare tuturor. Am vrut o soluție simplă și ieftină de backup pentru cele 12 site-uri pe care le administrez, fără să plătesc licențe anuale la monștrii din nișă. Backblaze B2 are prețuri excelente, așa că am decis să-mi scriu propriul plugin de WP, să-l fac open-source și să-l urc pe repo-ul oficial.
Procesul a fost o aventură destul de intensă, mai ales partea de review manual din partea echipei WordPress. Am învățat câteva lecții dure pe parcurs și am vrut să le împărtășesc cu voi.
De ce B2 și care e compromisul?
La un preț de 6$ per TB pe lună, B2 e imbatabil comparat cu S3 sau Google Cloud. Totuși, am vrut ca pluginul să rămână extrem de ușor. AWS SDK pentru PHP are în jur de 4-5 MB și vine cu o grămadă de dependențe. Pentru pluginul meu, am decis să scriu un client B2 nativ, folosind doar wp_remote_post și wp_remote_get din core-ul WP.
Rezultatul? Un plugin care are sub 180KB în format zip. Trade-off-ul e evident: pluginul face DOAR backup în Backblaze B2. Dacă vrei Dropbox, Google Drive sau FTP, folosești altceva. Am preferat să fac un singur lucru, dar să-l fac bine și fără overhead.
Coșmarul numit "WordPress.org Review Queue"
Dacă n-ați mai trimis un plugin la review în ultimul an, înarmați-vă cu răbdare. Am așteptat exact 22 de zile doar ca să se uite cineva peste cod. Când am primit primul răspuns, am fost respins instant din trei motive:
- Lipsa de sanitizare și escapare: Chiar dacă e o pagină de admin accesibilă doar administratorilor, trebuie să folosești
esc_html(),esc_attr()șisanitize_text_field()absolut peste tot. Am ratat vreo două inputuri de configurare și mi-au dat peste mână. - Prefixarea globală: Toate funcțiile, clasele și opțiunile din baza de date trebuie să aibă un prefix unic (ex:
wp_b2_backup_). Am avut o funcție helper numită simpluformat_bytes()și a trebuit să o namespacesc corespunzător. - Nonces pentru securitate: Orice acțiune AJAX sau salvare de formular trebuie validată cu
wp_verify_nonce.
După ce am rezolvat astea în 2 ore, am mai așteptat încă 4 zile pentru aprobarea finală. Acum pluginul este live și stabil.
Cum am rezolvat uploadul fișierelor mari
La primele teste pe un site real cu o bază de date de 1.2GB și un folder de uploaduri de peste 8GB, PHP-ul crăpa glorios din cauza epuizării memoriei. B2 API nu îți permite să trimiți fișiere uriașe într-un singur request HTTP simplu dacă ai resurse limitate pe server (cum se întâmplă pe shared hosting).
Am implementat un sistem de chunked upload folosind API-ul de "Large Files" de la Backblaze. Sparg arhiva în bucăți de exact 5MB folosind fseek și fread, le uploadez pe rând, iar la final trimit un request de commit. Consumul de memorie RAM a scăzut cu peste 60%, rămânând constant la aproximativ 24MB pe toată durata procesului de upload.
Mai jos aveți logica prin care citesc și trimit doar o bucată din fișier, fără să încarc toată arhiva în memorie.
Voi ce soluții de backup folosiți pentru clienți și cât de des vă loviți de limitele de memorie pe shared hosting?