PHP – create class properties at runtime

How to dynamically create  in PHP a property for an object?

If the object¬† is $foo you use this syntax: $this->{$property} = ‘a value’;

For example:

<?php

class foo {

public function setProperty($n, $v)
{
   $this->{$n} = $v;
}

}

$foo = new foo();
$foo->setProperty('property1','value1');
echo $foo->property1; //will display value1
?>

Security : crypter class….the easy way

In this article I will explain how to create a PHP Class that will encrypt and decrypt any data with a given password. It is object programmed and uses existing PHP algorithms.

Excerpt :

Think about what we might need a class like this for? We want to encrypt important data with a password for security reasons. We also want, as already mentioned, to be able to decrypt that data when necessary. Why should you use symmetric algorithms? It’s easy; when you’re offering a password sent via email or something like that, you need the password to be sent in plaintext. The hash algorithms are not reversible. Once you have hashed a string you can’t decipher the original text from the hash.

Source : here

Learning cURL

cURL is a tool for transferring files and data with URL syntax, supporting many protocols including HTTP, FTP, TELNET and more. Initially, cURL was designed to be a command line tool. Lucky for us, the cURL library is also supported by PHP. In this article, we will look at some of the advanced features of cURL, and how we can use them in our PHP scripts.

Source : here

cURL , PHP si SSL

La un moment dat am avut nevoie de a accesa un serviciu ssl din php folosind cURL. NU intentionam sa folosesc cURL, dar asta folosea PEAR : SOAP. Dupa mai mutle incercari, gaseam eroarea de ssl, de certificat invalid.

Rezolvarea e una simpla : Dezactivam din cURL verificarea PEER (CURLOPT_SSL_VERIFYPEER), insa nu e elegant.
Metoda eleganta presupune insa, salvarea certificatului si trimiterea lui in requestul cURL.

Trimiterea se face astfel :

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, 'fisierul in care se tine certificatul salvat in format PEM');

Fisierul trebuie sa fie salvat in format X.509 Certificate (PEM). Asta se paote face din browser, la view certificate/export.

Ce facem insa cand aplicatia ruleaza si se depaseste expire date ?
Folosind functiile php stream, putem accesa certificatul. Cu ajutorul extensiei openssl il putem salva.


$url = 'url'; //url-ul care necesita certificatul ,fara protocol.
$context = stream_context_create();
$res = stream_context_set_option($context, 'ssl', 'capture_peer_cert', true);
$res = stream_context_set_option($context, 'ssl', 'verify_host', true);
if ($socket = stream_socket_client("tls://$url:443/", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context))
{
    if ($options = stream_context_get_options($context))
    {
      if ( isset ($options['ssl']) && isset ($options['ssl']['peer_certificate']))
      {
        $keyinfo = openssl_x509_export_to_file($options['ssl']['peer_certificate'], 'file to save to');
      }
    }
}

Data de expirare a certificatului curent se poate lua astfel :

$keyinfo = openssl_x509_parse(file_get_contents($filename));
var_dump($keyinfo['validTo']);

Data este in format YYMMDDHHMMSS.

Spor la conectare SSL.

Watermark pe imagini in php

Va propun o metoda de a pune un watermark pe o imagine in PHP. In principiu functia primeste ca parametrii imaginea sursa (locatie), locatia destinatie, watermarkul (locatie imagine), si calitatea jpeg.

Va returna Boolean, iar in cazul TRUE va salva un jpeg cu watermark din imaginea initiala. Functia se foloseste de libraria GD inclusa in php si accepta orice fel de tip de imagine pe care o poate recunoaste aceasta.

Watermarkul este pus in coltul din dreapta jos, dar asta se paote modifica dupa bunul plac.

function set_watermark($source, $dest, $watermark, $quality = 80)
{
  if (func_num_args() < 3)
  {
    $set_watermark_error = "Insufficient parameters supplied!";
  }
  else
  {
    if (file_exists($source))
    {
      if ($src = imagecreatefromstring(file_get_contents($source)))
      {
        $info = getimagesize($source);
        imageantialias($src, true);
        if ($wm = imagecreatefromstring(file_get_contents($watermark)))
        {
          $wm_info = getimagesize($watermark);
          imagealphablending($src, true);
          imagecopy($src, $wm, $info[0]-$wm_info[0]-5, $info[1]-$wm_info[1]-5, 0, 0, $wm_info[0], $wm_info[1]);
          if (imagejpeg($src, $dest, $quality))
          {
            if (file_exists($dest))
            {
              chmod($dest, 0777);
              return true;
            }
            else
            {
              $set_watermark_error = 'Unable tosaveimage! ';
            }
          }
          else
          {
            $set_watermark_error = 'Unable tosaveimage! ';
          }
        }
      }
      else
      {
        $set_watermark_error = 'Unrecognized imageformat! ';
      }
    }
    else
    {
      $set_watermark_error = 'Source filedoesnotexist! ';
    }
  }
  return false;
}

Functia mai poate fi customizata pentru a intoarce si alte tipuri de imagine, dar lasam asta la alegerea fiecaruia.

Extragere date din cnp (php)

Va propun un cod de extragere de date specifice dintr-un CNP (13 cifre). Aceste date ar putea fi sex, an,luna,zi, data nasterii,judet,nr si crc.

function cnp_extract($cnp, $extract_type)
{
  if (strlen($cnp) == 13)
  {
    $sex = $cnp[0];
    $bd = substr($cnp, 1, 6);
    if ($sex == 1 || $sex == 2) { $sy = 19; }
    elseif ($sex == 3 || $sex == 4) { $sy = 18; }
    elseif ($sex == 5 || $sex == 6) { $sy = 20; }
    $year = $sy.$bd[0].$bd[1];
    $month = $bd[2].$bd[3];
    $day = $bd[4].$bd[5];
    $birthday = strtotime("$year-$month-$day");
    $judet = $cnp[7].$cnp[8];
    $nr = $cnp[9].$cnp[10].$cnp[11];
    $crc = $cnp[12];
    if(isset($$extract_type)
    {
      return $$extract_type;
    }
    else
    {
      return false;
    }
  }
  else
  {
    return false;
  }
}

Astfel callul : cnp_extract($cnp, 'birthday') va intoarce data nasterii.

Captcha – Mai simplu nu se poate

O mare problema in ziua de azi este spam-ul.
Cea mai simpla modalitate de a evita spam-ul este folosind Captcha. Aceasta face diferenta intre un calculator si o fiinta umana. Un calculator nu poate citi ceea ce scrie intr-o imagine, de aceea vom folosi si noi o poza.

Incepem prin a creea fisierul poza.php. Acest fisier va creea o poza cu un text ales de noi.


header('Content-type: image/jpeg'); // Acest fisier va afisa o poza in format jpg
$width = 60; // Latimea pozei ce va fi creata
$height = 24; // Inaltimea pozei ce va fi creata
$my_image = imagecreatetruecolor($width, $height); // Poza propriu-zisa este creata
imagefill($my_image, 0, 0, 0xFFFFFF); // Fundalul pozei va fi alb

Pana acum am creat o imagine cu o latime de 60 pixeli, o inaltime de 24 de pixeli si fundal alb.
Adaugam putine distorsiuni:

for ($c = 0; $c < 40; $c++){ $x = rand(0,$width-1); $y = rand(0,$height-1); imagesetpixel($my_image, $x, $y, 0x000000); }

Am inserat 40 de pixeli de culoarea neagra. Acesti pixeli vor avea coordonate aleatorii de fiecare data cand o poza este afisata.

Scriem pe poza si textul necesar:


$x = rand(1,10); // Coordonata X a coltului stanga sus.
$y = rand(1,10); // Coordonata Y a coltului stanga sus
$rand_string = rand(10000,99999); // Obtinerea unui numar aleatoriu intre 10000 si 99999
imagestring($my_image, 5, $x, $y, $rand_string, 0x000000); // Numarul aleatoriu obtinut mai devreme este scris in poza

Acum vom salva string-ul din poza intr-un cookie. Acest cookie va fi citit in momentul in care un user completeaza un form si comparat cu valoarea introdusa de el in campul de verificare.

setcookie("cookie-captcha", (md5($rand_string)), time()+3600, "/"); // Setam un cookie in care salvam valoarea codata a stringului obtinut mai devreme ($rand_string).
imagejpeg($my_image); // Crearea pozei in format jpg
imagedestroy($my_image); // Poza este stearsa

In acest exemplu cookie-ul se numeste cookie-captcha, continutul acesteia va fi valoarea codata a $rand_string, este valabil o ora (time()+3600) pe tot domeniul dumneavoastra ( "/" )

Poza este stearsa (imagedestroy) pentru a salva spatiu pe server. Imaginati-va ca aveti 10000 de vizitatori pe ora - vor fi create 24000 de astfel de poze si vor ramane pe server-ul dumneavoastra.

Fisierul complet poza.php va fi:


<?php
header('Content-type: image/jpeg');
$width = 60;
$height = 24;
$my_image = imagecreatetruecolor($width, $height);
imagefill($my_image, 0, 0, 0xFFFFFF);
for ($c = 0; $c < 40; $c++){ $x = rand(0,$width-1); $y = rand(0,$height-1); imagesetpixel($my_image, $x, $y, 0x000000); } $x = rand(1,10); $y = rand(1,10); $rand_string = rand(10000,99999); imagestring($my_image, 5, $x, $y, $rand_string, 0x000000); setcookie("cookie-captcha", (md5($rand_string)), time()+3600, "/"); imagejpeg($my_image); imagedestroy($my_image); ?>

Acum ca poza este creata si valoarea scrisa in poza este codata in cookie este timpul sa validam.
Poza creata de poza.php va fi inserata in html ca o poza normala:

<img src="poza.php" alt="Poza de verificare" />

Sa nu uitam de input:

<input type="text" name="numar_verificare" size="5" max-length="5" />

Definim variabilele:


$numar_verificare = $_REQUEST['numar_verificare'];
$text_corect = $_COOKIE['cookie-captcha']);

Nu uitati ca in cookie valoarea din poza este criptata md5.
Acum comparam textul introdus de utilizator (criptat md5) cu cel aflat in cookie:


<?php
if(md5($numar_verificare) != $_COOKIE['cookie-captcha']){
echo 'Ne pare rau dar textul introdus nu corespunde cu cel din imagine';
}
else
{
echo 'Textul corespunde cu cel din imagine.';
}
>

Bineinteles ca in locul echo-ului 'Textul corespunde cu cel din imagine.' veti pune un mysql_query sau ce aveti nevoie.

Puteti vedea si un exemplu aici.

Am implementat captcha complet functional cu doar 17 linii de cod.

Afisare timp trecut in PHP in orice format

Probabil ati observat pe digg ca este afisat timpul scurs de la postarea unui comentariu in urmatorul format:

digg

Pentru a obtine un astfel de rezultat vom folosi functia strtotime. Aceasta functie numara secundele trecute de la 1 Ianuarie 1970.

Pentru a putea obtine cu exactitate numarul de secunde ar trebui sa salvam data postarii unui comentariu in urmatorul format: date(‘Y-m-d H:i:s’) – va returna 2008-11-12 14:39:53

La crearea fieldului data in tabela MySQL alegeti tipul datetime.

Incepem cu adaugarea in tabela MySQL a comentariului.

INSERT INTO `comments` (`nume` , `comentariu`, `data`) VALUES ('Sava Stefan', 'Acesta este un comentariu', NOW( ));

NOW() va insera valoarea exacta a timpului in acel moment in format 2008-11-12 14:39:53.

Acum ca avem un comentariu este timpul sa afisam timpul trecut.
Voi nota data postarii acestui comentariu cu $datacomentariu. Shtiti voi cum sa il obtineti :-).

Vom crea o functie numita countTime.

function countTime($datacomentariu) {
$now = date('Y-m-d H:i:s');
$nrsecunde = (strtotime($now) - strtotime($datacomentariu));
}

Pana acum am obtinut numarul de secunde ce au trecut de la postarea comentariului ($datacomentariu).
Trecem mai departe si vom afla nr de zile, ore si minute trecute prin simple operatiuni matematice.


$nrminute = $nrsecunde / (60);
$nrore = $nrminute / (60);
$nrminuteafisat = intval($nrminute - ($nroreafisat * 60));
$nroreafisat = intval($nrore);

Dupa cum vedeti numarul de minute trecute este egal cu numarul de secunde obtinut mai devreme (diferenta) impartit la 60. Numarul de ore va fi la randul sau egal cu numarul de minute impartit la 60.

Am folosit intval pentru a obtine numarul intreg de ore si minute ce vor fi afisate.

Numarul de secunde afisat va fi si el un numar intreg:

$nrsecundeafisat = intval($nrsecunde - ($nroreafisat * 60 * 60) - ($nrminuteafisat * 60));

$nroreafisat * 60 * 60 = numarul de secunde in $x ore; daca $nroreafisat = 1 vom avea 3600 de secunde
$nrminuteafisat * 60 = numarul de secunde in $x minute; daca $nrminuteafisat = 2 vom avea 120 de secunde.

Acum sa customizam putin output-ul acestei functii:
echo 'comentariu postat acum '.$nroreafisat.' ore, '.$nrminuteafisat.' minute si '.$nrsecundeafisat.' secunde';

Functia completa:


function countTime($datacomentariu) {
$now = date('Y-m-d H:i:s');
$nrsecunde = (strtotime($now) - strtotime($datacomentariu));
$nrminute = $nrsecunde / (60);
$nrore = $nrminute / (60);
$nrminuteafisat = intval($nrminute - ($nroreafisat * 60));
$nroreafisat = intval($nrore);
$nrsecundeafisat = intval($nrsecunde - ($nroreafisat * 60 * 60) - ($nrminuteafisat * 60));
echo 'Postat acum '.$nroreafisat.' ore, '.$nrminuteafisat.' de minute si '.$nrsecundeafisat.' secunde';
}

Integrarea acestei functii se face foarte simplu. $comentariu[‘data’] este data postarii comentariului din baza de date.

Nume: $comentariu['nume'];
Comentariu: $comentariu['comentariu'];
countTime($comentariu['data']);

Va fi afisat:


Nume: Sava Stefan
Comentariu: Acesta este un comentariu
Postat acum 3 ore, 24 de minute si 13 secunde

Bineinteles ca puteti calcula si timpul ramas pana la o anumita data scazand din data limita data curenta:
$nrsecunderamase = (strtotime($dataincauza) - strtotime($now));