Cache simplu in PHP fara alte extensii

Se întâmplă destul de des să ai nevoie să implementezi o funcționalitate de cache date, dar să nu ai acces la APC, Memcache sau orice altceva preferi tu sa folosești. Ce urmează este o metodă simplă să implementezi cache pentru o aplicație. Tot ce îți trebuie e un director writable pe server.

Implementarea

Mecanismul este format din trei funcții:

  1. Funcția writeCache ia datele, le serializează (dacă e nevoie) și apoi le scrie într-un fișier static.
  2. Funcția checkCache citește data la care a fost modificat ultima oară fișierul de cache si compară această dată cu un anumit număr de minute (predefinit printr-o variabilă globală). Dacă fișierul de cache trebuie actualizat, funcția returnează false
  3. Funcția readCache citește conținutul fișierului de cache, deserializează datele (dacă e nevoie) și le returnează
/*the base folder of the cache file(s) 
 * (assuming there are no open_basedir restrictions)
*/
$cacheFileBase = $_SERVER['DOCUMENT_ROOT'] . '/cache/';
 
/*the cache time in minutes - how long will the results be cached*/
$cacheTime = 10;
 
/*Function to check if a certain cache file needs to be updated*/
function checkCache( $identificator ) {
	global $cacheFileBase, $cacheTime;
 
	$file = $cacheFileBase . $identificator . '.txt';
 
	/*return false if the cache file doesn't exist*/
	if( !file_exists( $file ) ) {
		return false;
	}
 
	/*Return false if the file's cache time substracted 
	 * from the current time is larger than the cache time in seconds*/
	if( (time() - filemtime($file)) > $cacheTime * 60) {
		return false;
	}
 
	return true;
}
 
function writeCache( $identificator, $data ) {
	global $cacheFileBase;
 
	/*The full path to the cache file*/
	$file = $cacheFileBase . $identificator . '.txt';
 
	/*serialize the data if we're dealing with an array or an object*/
	if( is_array($data) || is_object($data) ) {
		$data = serialize($data);
	}
 
	if( file_put_contents($file, $data) ) {
		return true;
	}
 
	return false;
}
 
function readCache( $identificator ) {
	global $cacheFileBase;
 
	/*The full path to the cache file*/
	$file = $cacheFileBase . $identificator . '.txt';
 
	$data = file_get_contents($file);
 
	/*check to see if the data was 
	 * serialized so we know what to return
	 * http://stackoverflow.com/questions/2878218/check-if-string-is-serialized-in-php/2878254#2878254
	 * */
	$checkSerialization = @unserialize($data);
	if ( $checkSerialization !== false || $data === 'b:0;' ) {
	    $data = $checkSerialization;
	}
 
	return $data;
 
}

Cum se folosește

if( !checkCache('testing') ) {
	$test_data = array('test1', 'test2', 'test3');
 
	if( !writeCache('testing', $test_data) ) {
		//log the data if cache failed
	}
 
} else {
	$test_data = readCache('testing');
}
 
print_r($test_data);

Trimite e-mail-uri eficient cu Amazon SES si CakePHP

Câteva cuvinte despre Amazon SES

Amazon SES este un serviciu de e-mail dezvoltat de Amazon ce permite trimiterea profesională de e-mail-uri prin serverele Amazon. Se ocupă de trimiterea și procesarea e-mailurilor (trimiterea, validarea adreselor de e-mail, procesarea erorilor) în locul tău. Personal, folosesc SES pentru a mă asigura că am cel mai bun raport de livrabilitate pentru notificările trimise din aplicațiile mele.

Gratuit?

Nu, dar merită fiecare leu. Nu o sa te sece la buzuare, totuși. Prețurile încep de la 10 cenți per 1000 de e-mailuri trimise și sunt chiar mai mici dacă folosești soluțiile cloud de la Amazon pentru hosting.

Să ne apucăm de treabă

Prima oară, o sa ne ocupăm de implementarea din CakePHP:

Descarcă SDK-ul PHP pregătit de Amazon de aici, redenumește directorul aws-sdk și urcă-l în directorul /app/vendors/ din instalarea ta de CakePHP.

După ce ai copiat SDK-ul PHP, o să ai nevoie de o componentă simplă care extinde componenta de e-mail nativă a CakePHP, astfel încât să folosească SES. O poți descărca de pe contul meu de Github (e o versiune puțin modificată a unei componente excelente dezvoltate de Lucas Ferreira). Copiază componenta in directorul tău /app/ păstrând structura de directoare.

Presupunând că nu ai deja un cont Amazon AWS (ce include și SES), creează unul aici. Cum acesta nu este un serviciu gratuit, va trebui să introduci un număr de card înainte de a finaliza înregistrarea. Activarea tuturor serviciilor o să dureze câteva minute.

După activarea serviciilor, o sa fie nevoie să te întorci la directorul în care ai SDK-ul PHP în instalarea ta de CakePHP pentru a crea fișierul de configurare. Redenumește config-sample.inc.php în config.inc.php și adaugă-ți propriile valori pentru AWS_KEY, AWS_SECRET_KEY, AWS_ACCOUNT_ID și AWS_CANONICAL_ID. Găsești toate aceste numere în aceeași pagină, în secțiunea Security Credentials din pagina contului tău.

Testarea

Amazon SES are nevoie de access la un mediu de producție ca să poată să funcționeze fără restricții. Asta se întâmplă pentru că obiectul SES este unul puțin sensibil, iar cei de la Amazon trebuie să îi aleagă manual pe cei ce le vor folosi serviciile. Asta împiedică spammerii să folosească SES în scopuri ilegale.

Totuși, o să ai acces sandbox. Asta înseamnă că vei putea folosi toate funcționalitățile serviciului, dar numai pe adrese pe care le-ai definit (verificat) anterior. O să fie nevoie să verifici atât adresele de pe care trimiți e-mailuri (această măsură se va aplica și în mediul de producție), cât și adresele care vor primi e-mailuri. Odată ce vei avea acces la mediul de producție, nu va mai fi nevoie să verifici adresele către care trimiți mesaje. Procesul de verificare constă în trimiterea unei cereri pentru adresa dorită și apoi accesarea unui link dintr-un mesaj trimis pe acea adresă.

Poți verifica o adresă de e-mail prin apelarea unei metode din componenta EmailService pe care ai descărcat-o mai devrene de pe github:

class PagesController extends AppController {
 
	var $name = 'Pages';
	var $components = array('EmailService');
 
	function beforeFilter() {
 
	}
 
	function display() {
		$verify = $this->EmailService->verifyEmailAddress('me@example.com');
		var_dump($verify);
	}
 
}

Relativ la componenta originală de trimis e-mail-uri a CakePHP, metoda de utilizare este aproximativ aceeași. Ca adiție, o să fie nevoie să specifici componentei de Email ce fel de e-mail-uri vrei să trimiți. Restul este la fel, cu mențiunea că va trebui să folosești $this->EmailService în loc de of $this->Email. Un exemplu:

class PagesController extends AppController {
 
	var $name = 'Pages';
	var $components = array('EmailService');
 
	function display() {
		$this->EmailService->delivery = 'aws_ses'; //sau aws_ses_raw
		$this->EmailService->to = array('me@example.com');
		$this->EmailService->subject = 'Example e-mail';
		$this->EmailService->from = 'Me <meagain@example.com>';
		$this->EmailService->template = 'template';
		$this->EmailService->sendAs = 'html';
		$this->EmailService->send();
	}
 
}

Livrare prin aws_ses sau aws_ses_raw?

Asta depinde de cum este construit corpul e-mail-ului. După o serie de teste, am ajuns la concluzia că aws_ses este potrivit pentru mesajele plain text și pentru mesajele cu markup HTML simplu (fără imagini), iar aws_ses_raw este mai potrivit pentru mesaje cu markup HTML complex (text și imagini) și e-mail-uri ce conțin atașamente.

…în sfârșit. Aplicarea pentru acces la mediul de producție

Accesează acest formular simplu și completează-l cu detaliile tale. Vei primi acces la mediul de producție imediat cum îți vor analiza cererea.

Instalare și setup Subversion (SVN) pe o mașină WHM/Cpanel

Intenționez ca acest post să conțină un set de instrucțiuni complete pentru instalarea și setup-ul Subversion pe o mașină WHM/Cpanel

Note:
1. Ce urmează a fost testat pe WHM versiunea 11.30.4 (build 6), instalat în CentOS 5.7
2. O să fie folosite următoarele referințe:
example = numele contului cPanel setat în WHM
example.com = domeniul pentru care a fost setat contul example
3. O să trebuiască să te “murdărești” puțin umblând prin consolă
4. Instalarea descrisă folosește modulul mod_dav al Apache pentru autentificarea utilizatorilor

Instalarea mod_dav (dacă este nevoie)

Întâi de toate, controlează dacă mod_dav nu este deja instalat, rulând următoarea comandă în terminal:

root@machine [~]# /sbin/service httpd -M | grep dav

Dacă mod_dav este deja instalat, o să returneze:

dav_module (static)
dav_fs_module (static)

Dacă nu, o să trebuiască să rulezi din nou EasyApache (EasyApache este un script folosit de instalările WHM pentru a configura – compila și recompila – Apache). Poți face asta apăsând pe link-ul “EasyApache (Apache Update)” în meniul WHM. Selectează cel mai potrivit profil, în funcție de scopul în care va folosit serverul (dacă nu este o instalare nouă de WHM, este bine să citești documentația EasyApache înainte să continui, astfel încât să nu pierzi configurația inițială). Când ajungi la pasul al șaselea (Exhaustive Options List), ai grijă să bifezi DavFS și Dav în lista Apache Built-in Modules. Save and build.
Notă: Rularea EasyApache o să dezactiveze webserver-ul pentru aproximativ cinci minute.

Instalarea Subversion

Pentru o configurare corectă, Subversion trebuie să fie compilat din surse. În primul rând, mergi la http://subversion.apache.org/download/#recommended-release și copiază link-ul către arhiva .tar.gz (în cazul meu, http://subversion.tigris.org/downloads/subversion-1.6.17.tar.gz). Apoi, descarcă sursa și dezarhiveaz-o:

root@machine [~]# cd /usr/local/src/
root@machine [/usr/local/src]# wget http://subversion.tigris.org/downloads/subversion-1.6.17.tar.gz
root@machine [/usr/local/src]# tar -xvf subversion-1.6.17.tar.gz

Înainte de compilarea Subversion, SQLite trebuie copiat în sursele sus-numite. Mergi la http://www.sqlite.org/download.html și ia link-ul către ultima arhivă .tar.gz. În cazul meu, acesta este http://www.sqlite.org/sqlite-autoconf-3070800.tar.gz:

root@machine [/usr/local/src]# wget http://www.sqlite.org/sqlite-autoconf-3070800.tar.gz
root@machine [/usr/local/src]# tar -xvf sqlite-autoconf-3070800.tar.gz
root@machine [/usr/local/src]# cd subversion-1.6.17
root@machine [/usr/local/src/subversion-1.6.17]# mkdir sqlite-amalgamation
root@machine [/usr/local/src/subversion-1.6.17]# cp ../sqlite-autoconf-3070800/sqlite3.c ./sqlite-amalgamation/

Acum, Subversion trebuie configurat și instalat:

root@machine [/usr/local/src/subversion-1.6.17]# ./configure --with-apxs=/usr/local/apache/bin/apxs --with-apr=/home/cpeasyapache/src/httpd-2.2.19/srclib/apr --with-apr-util=/home/cpeasyapache/src/httpd-2.2.19/srclib/apr-util
root@machine [/usr/local/src/subversion-1.6.17]# make && make install

S-ar putea să fie nevoie să actualizezi calea către httpd, dacă primești următoarea eroare:

checking for APR... configure: error: the --with-apr parameter is incorrect. It must specify an install prefix, a build directory, or an apr-config file.
 
root@machine [/usr/local/src/subversion-1.6.17]# cd /home/cpeasyapache/src/
root@machine [/home/cpeasyapache/src]# ls -all

Caută httpd-*.*.** (în locul stelelor găsești versiunea ta) și fă actualizarea. cd înapoi la directorul Subversion și rulează din nou configure, make și make install.

Subversion și Apache

Dat fiind că folosești WHM și WHM folosește EasyApache, nu poți să modifici configurația Apache, pur și simplu, astfel încât să includă modulele Subversion. În schimb trebuie să folosești “Include Editor”, pe care îl poți găsi mergând la “Apache Configuration” în meniul WHM. Acolo trebuie să folosești Pre Main Include. Alege ultima versiune de Apache din listă și o să îți apară un textarea. Adaugă următoarele linii și apasă “Update”:

LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

Adaugă utilizatori Subversion

Rulează următoarea comandă pentru fiecare utilizator pe care vrei să îl adaugi. O sa ți se ceară o parolă pentru fiecare:

root@machine [~]# /usr/local/apache/bin/htpasswd -cm /etc/svn-auth-conf username

Setup-ul primului repository

Presupun că vei seta mai mult de un repository per domeniu, dar instrucțiunile care urmează se aplică și când vrei să setezi doar unul.

Prima și prima oară, trebuie să adaugi un virtual host pentru repository-ul tău:

root@machine [~]# cd /etc/httpd/conf/userdata/std/2/

Dacă primești eroarea “-bash: cd: /etc/httpd/conf/userdata/std/2/: No such file or directory”, rulează aceste comenzi pentru a crea directoarele necesare:

root@machine [~]# mkdir /etc/httpd/conf/userdata
root@machine [~]# mkdir /etc/httpd/conf/userdata/std
root@machine [~]# mkdir /etc/httpd/conf/userdata/std/2

Adaugă un director pentru domeniul tău:

root@machine [~]# mkdir /etc/httpd/conf/userdata/std/2/example
root@machine [~]# mkdir /etc/httpd/conf/userdata/std/2/example/example.com
root@machine [~]# cd /etc/httpd/conf/userdata/std/2/example/example.com

Creează fișierul de configurare Subversion:

root@machine [/etc/httpd/conf/userdata/std/2/example/example.com]# nano svn_custom.conf

Fă copy/paste următoarelor rânduri în fișierul de configurare și salvează-l. Pentru fiecare repository pe care vrei să-l creezi, adaugă câte un tag <location>.

<IfModule mod_dav_svn.c>
    #begin location
    <location /repo>
	DAV svn
	SVNPath /home/example/public_svn/repo/svn/
	AuthType Basic
	AuthName "SVN Repo"
	AuthUserFile /home/example/.svn.htpasswd
	Require valid-user
    </location>
    #end location
</IfModule>

A se observa că folosim un director numit public_svn, în afară directorului public_html. Nu este recomandat să adaugi repository-uri în același loc ca fișierele webserver-ului, deoarece Apache va fi derutat când vei încerca să accesezi repository-ul printr-o interfață locală de Subversion. Chiar dacă vei putea să încarci repository-ul în browser, o să primești o eroare (“Repository moved permanently to ‘http://example.com/repo/’; please relocate”) când vei încerca să îl accesezi remote. Asta se întâmplă pentru că Apache nu știe cum să răspundă cererii și nu va ști ce să servească (un director local prin http sau repository-ul tău).

Acum, creează fișierele repository-ului tău:

root@machine [~]# su example
example@machine [/root]# cd ~
example@machine [~]# mkdir public_svn
example@machine [~]# mkdir public_svn/repo
example@machine [~]# cd public_svn/repo
example@machine [~/public_svn/repo]# svnadmin create svn
example@machine [~/public_svn/repo]# chmod 775 -R svn
example@machine [~/public_svn/repo]# exit

Update la configurația Apache și gata:

/scripts/ensure_vhost_includes --all-users

Mergi la http://example.com/repo în browser, ca să îți testezi repository-ul. Ar trebui să îți ceară un user și o parolă și să-ți arate următoarele: