Kategorien
PHP PHPUnit Testing

PDOException: You cannot serialize or unserialize PDO instances

Beim Mocken von Objekten mit PHPunit kann es zur Fehlermeldung:

PDOException: You cannot serialize or unserialize PDO instances

kommen, immer dann, wenn im Constructor eine PDO Instanz injeziert wird. Dies kann unterbunden werden durch:

class PDOMock extends PDO{
    public function __construct(){}
}
Kategorien
PHP

PHP Wie verwendet man password_verify, password_hash und password_needs_rehash richtig

Mit der ab PHP 5.5. eingeführten Passwort-Hash Funktionalität kann man das Problem umgehen, dass ständig neue Hash Funktionen benutzen werden müssen, weil die alte zu leicht knackbar ist.

Bei bestehenden Projekten steht man dann an dem Punkt, wo man bestehenden Hashes in der Datenbank hat und diese nicht einfach neu hashen kann, weil man den Klartext nicht kennt. Diese Funktionalität wird einem durch die neue password_verify Funktion abgenommen.

So könnte ein neues Login-Funktion aussehen, welches dieses Problem umgeht. Beim Anheben der Hash-Sicherheit (Zeitdauer zum Berechnen des Hashes) kann man den Wert $currentHashOption[‚cost‘] erhöhen

$username = 'asd@asdasd.de';
$password = 'xxxxxx';

$user = User::findByName($username);

if(password_verify($password, $user->password_hash) === false){
 throw new Exception('Invalid Login');
}
$currentHashAlgorithm = PASSWORD_DEFAULT;
$currentHashOption = ['cost' => 15];

$passwordsNeedsRehash = password_needs_rehash(
 $user->password_hash,
 $algorithm = $currentHashAlgorithm,
 $currentHashOption
);
if($passwordsNeedsRehash === true){
 $user->password_hash = password_hash($password, $currentHashAlgorithm, $currentHashOption);
 $user->save();
}
Kategorien
PHP Server Administration

Analyse von sehr großen gzip/bzip2 gepackten Log-Dateien per Stream

Man kann per Stream in PHP beim verarbeiten der Daten sehr große Log-Dateien, die mehrere GB groß sind, sehr leicht analysieren mit Hilfe von Stream Compression Filter.

Damit kann die Datei ohne sie komplett in den Speicher laden zu müssen entpackt und analysiert werden beim Einlesen der Datei.

Dadurch kann man während des einlesens der Log-Datei schon nach beliebigen Stellen im Code suchen:

$file = 'X:/file.log.bz2';
$searchString = '2017-01-01';

if(file_exists($file)){
   $handle = fopen($file, 'r');
   stream_filter_append($handle, 'bzip2.decompress');
   while(!feof($handle)){
      $line = fgets($handle);
      if(strpos($line, $searchString) !== false){
         echo $line;
      }
   }
   fclose($handle);
}
Kategorien
PHP

Verabreiten großer Dateien in PHP mittels Generator

Um große Datenmengen mit PHP zu verarbeiten benötigt man viel Memory Speicher, weil große Mengen Daten geladen und dann verarbeitet werden. Eine speichersparende Alternative bieten Generatoren ab PHP 5.5., die mit dem yield Befehl durch große Datenmengen iterieren können und nur Speicherplatz für einen Datensatz belegen.

Beispiel: Verarbeiten einer großen CSV Datei mittels Generators:

<?php
class CsvFile {

    protected $file;

    public function __construct($file) {
        $this->file = fopen($file, 'r');
    }

    public function parse() {
        while (!feof($this->file)) {
            yield fgetcsv($this->file);
        }
        return;
    }
}

$csv = new CsvFile('/pathTo/file.csv');
foreach ($csv->parse() as $row) {
    echo $row;
}
Kategorien
WordPress

WordPress Posts mit Links autoamtisch als Spam markieren

Damit man von dn ganzen Spam Bots nicht genervt wird, deren Zie es immer ist einen Kommentar mit einem oder mehreren Links auf ener Webseite zu platzieren, habe ich ein kurzes Skript geschrieben, was in die function.php eingefügt werden muss. Das Skript markiert alle Kommentare als Spam, die einen Link enthalten.

add_action( 'comment_post', 'show_message_function', 10, 2 );
function show_message_function( $comment_ID, $comment_approved ) {
   $comment = get_comment( $comment_ID);
   if(!empty($comment)){
      $content = $comment->comment_content;
      if(!empty($content)){
         $content = strtolower($content);
         $hasLink = strpos($content, 'http') !== false || strpos($content, 'www.') !== false || strpos($content, 'href') !== false;
         if($hasLink){
            //when has link, set to spam
            $commentarr = array();
            $commentarr['comment_ID'] = $comment_ID;
            $commentarr['comment_approved'] = 'spam';
            wp_update_comment( $commentarr );
         }
      }

   }

}
Kategorien
PHP Server Administration

PHP auf Linux Konsole on-the-fly ausführen

Wenn man einen kurzen PHP Befehl ausführen will auf der Konsole, kann man mit dem –run Parameter Code schnell und unkompliziert ausführen

php -r "echo 'hello world';"

//Ausgabe
hello world
Kategorien
PHP Server Administration

Stress Testing Tools

Zum Stress- bzw. Last-Testen von PHP Applikationen kann man das Tool Apache bench  oder Seige benutzen.

Damit lässt sich das Verhalten einer Applkation unter hoher Last testen.

Kategorien
PHP Server Administration Webdeveloper Tools

Server Management mit Forge

Ein sehr einfaches und gutes Tool für das Server Management von PHP Applikationen ist Laravel Forge, mit dem man seine App auf AWS, Digital Ocean oder Linode betreiben kann inkl.

  • Load Balancing
  • Cron Jobs
  • Domain-Management
  • SSL Zertifikate
  • Queues
Kategorien
PHP

PHP asynchornen Thread starten

Mit PHP kann man nativ keine asynchronen Threads starten, aber über das Betriebsystem natürlich schon. Mit dem Linux command „ab“ kann man sehr einfach einen neuen Thread erstellen und langlaufende Aktionen auslagern. Zum Escapen von shell Argumente kann mn die Funktion escapeshellarg benutzen.

 exec('echo "php create-report.php" | at now');
Kategorien
PHP

PHP PDO Connection Timeout für Datenbank setzen und bestimmen

Normalerweise soll man das Datenbank Connection Timeout in PHP auslesen können mittels:

$pdo = new PDO('mysql:host=localhost;port=80;dbname=xxx', 'xxx', 'xxxx');
$pdo->getAttribute(PDO::ATTR_TIMEOUT);

Allerdings gibt das bei meiner alten PDO Version die Fehlermeldung:

SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute

Also habe ich ein Testscript geschrieben, mit dem man das Timeout provozieren kann (das Messen der Zeit ist nicht enthalten, wäre nett, wenn jemand das posten könnte):

$pdo = new PDO('mysql:host=localhost;port=80;dbname=xxx', 'xxx', 'xxxx');

Damit wird das Timeout ausgelöst.

Um das Timeout zu verlängern, kann man den Parameter PDO::ATTR_TIMEOUT setzen:

$pdo = new PDO('mysql:host=localhost;port=80;dbname=xxx', 'xxx', 'xxxx', array(
   PDO::ATTR_TIMEOUT => 5
));