PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Archive for the ‘pecl’ tag

mysql_* Funktionen noch im Code?

with 5 comments

Heute eine kleine Umfrage. Es ist anonym und keiner muss sich rechtfertigen (kann aber natürlich gern in den Kommentaren, die Gründe sind sicher interessant!).

Es geht um die ext/mysql Extension, sprich die mysql_* Funktionen. In PHP 5.5 wurden sie DEPRECATED, d.h. es gibt eine Deprecation-Warnung im PHP-Error-Log dass die Funktionen nicht mehr benutzt werden sollen da sie bald entfernt werden.

Nun stehen die Planungen für PHP 5.6 an, und eine Frage ist: Soll ext/mysql entfernt werden, nachdem es in der letzten Version als veraltet markiert wurde? Entfernen heißt in diesem Zusammenhang: Verschieben aus dem Kern in die PECL Library. Wer es unbedingt noch braucht kann es also separat nachinstallieren. Im englischen PHP-Online-Manual gibt es große rote Warnungen dass es nicht mehr genutzt werden sollte, in der deutschen Variante aber leider nicht.

Hier also meine kleine Umfrage:

Nutzt du noch ext/mysql?

View Results

Wird geladen ... Wird geladen ...

Ich selbst habe aktuell ein kleines Kommandozeilenscript das ich umschreiben muss, und WordPress nutzt es noch, ansonsten bin ich Dank dem Zend Framework, welches PDO nutzt, glaube ich ext/mysql-frei.

Written by Michael Kliewe

Januar 21st, 2014 at 1:37 pm

Gearman Worker verbinden sich nach Upgrade nicht mehr

with 6 comments

Heute ein kurzer Tipp bezüglich PECL/gearman: Wenn ihr bei der Nutzung einer aktuellen Version den folgenden Fehler bekommt

send_packet(GEARMAN_COULD_NOT_CONNECT) Failed to send server-options packet
-> libgearman/connection.cc:430

dann liegt es daran dass ihr keinen Port beim Aufruf der Methode GearmanClient::addServer() angegeben habt. Bisher war der zweite Parameter optional und als Default wurde 4730 genommen, aber seit einigen Versionen (welcher genau kann ich nicht sagen) scheint er angegeben werden zu müssen. Wir benutzen aktuell PECL/gearman Version 1.1.1 kompiliert mit libgearman 1.1.5

Falls ihr also Gearman nutzt und den zweiten Parameter noch nicht gesetzt habt, fügt ihn am besten jetzt schon hinzu, damit ihr bei einem Upgrade in der Zukunft keine Probleme bekommt.

Hier habe ich die Lösung gefunden (wäre ich selbst wahrscheinlich nie drauf gekommen):
http://stackoverflow.com/questions/14883681/gearman-gives-me-gearman-could-not-connect-it-is-definitely-running
https://answers.launchpad.net/gearmand/+question/221277

Written by Michael Kliewe

April 8th, 2013 at 3:22 pm

Probleme mit libmemcached und PECL memcached Inkompatibilität

with 4 comments

Da wir uns bei mail.de wunderten warum eines unserer Preload-Scripte nicht so funktioniert wie es sollte, habe ich gestern und heute mehrere Stunden damit zugebracht herauszufinden woran das liegt.

Das Preload-Script ist eine Art Warmup-Script, es lädt gewisse Daten in den Memcached-Server die kurz darauf benötigt werden (könnten). Das Preload-Script läuft mittels Gearman auf eigenen Maschinen, getrennt von den Apache-Webservern.

Da wir neue Features erstmal in einer Umgebung testen die der Live-Umgebung sehr ähnlich ist (wir nennen sie PreLive, andere nennen sie staging), fiel uns da auf dass das Preloading nicht so funktionierte wie gewünscht. Auf unseren Entwicklermaschinen und in der kleinen lokalen Testumgebung ist es nicht aufgefallen da dort beides nicht getrennt ist.

Weiterlesen »

Written by Michael Kliewe

Juni 20th, 2012 at 2:35 pm

Posted in PHP

Tagged with , , ,

Ein PHP-Script als Windows-Dienst starten

with 38 comments

23dienstViele wichtige Dinge weltweit laufen permanent und tun endlos ihren Job. Webserver warten auf Besucher, Berechnungsprogramme rechnen Tag und Nacht, FTP-Server warten auf Datenübertragungen und SSH-Server warten auf Benutzer.

Auch mit PHP kann man all solche Dinge lösen. Es gibt bereits DNS-Server geschrieben in PHP, selbst ein Webserver in PHP ist verfügbar, ein Continuous Integration Server, einen FTP Server, und es gibt zig tausend Chat-Server (auf Socket-Basis, keine einfachen Webchats), die mit PHP erstellt wurden usw.

Wenn man plant, ein PHP-Script quasi permanent laufen zu lassen, gibt es 3 Möglichkeiten:

  1. Man startet das Script einmalig nach dem Rechnerstart und lässt es in einer Endlosschleife (while (true) { ) laufen
    • Linux: Cron Eintrag @reboot
    • Windows: Geplanter Task bei Rechnerstart
  2. Wenn das Script beispielsweise 2 Minuten für seine Arbeit braucht, startet man es alle 3 Minuten
    • Linux: Cron Eintrag  */3 * * * *
    • Windows: Geplanter Task alle 3 Minuten
  3. Man installiert das Script als Dienst und lässt es darüber automatisch laufen und kann es starten/stoppen
    • Linux: mit Hilfe der Runlevel-Scripte (rc.d / init.d etc)
    • Windows: Windows-Dienste

Hier will ich besonders auf die Windows-Dienste eingehen. Unter Windows ist das die einzige Art, ein PHP-Script beim System-Shutdown kontrolliert beenden zu lassen, denn PHP beherrscht unter Windows keine Signalverarbeitung. Es kann also keine Betriebssystem-Signale empfangen wie zB SIGTERM oder SIGHUP, wohingehen es unter Linux die PHP-Funktionen PCNTL zur Prozesskontrolle gibt. Ohne diese Signale läuft das PHP-Script also solange, bis es vom Betriebssystem gekillt wird (hart, also mitten im Ablauf irgendwo im Code), was natürlich große Probleme bereiten kann bei komplizierten Scripten.

Ein Dienst löst also dieses Problem, denn wenn ein Betriebssystem herunterfährt, gibt es seinen Diensten die Möglichkeit, sich selbst innerhalb einiger Sekunden zu beenden. Dazu muß das PHP-Script natürlich ab und zu in einen definierten Zustand gelangen, wo es „aussteigen“ kann.

Vielleicht sieht man es besser am Code:

while (WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {
	// hier kommt der Code, der ausgeführt werden soll
}

Es gibt also eine Funktion win32_get_last_control_message(), die dem Script sagt, ob es sich beenden soll oder nicht. Damit diese Funktion (und einige weitere) zur Verfügung stehen, benötigt man die extention win32service aus der PECL.

Aber wie installiere ich nun dieses PHP-Script als Dienst? Dazu gibt es auch eine Funktion. Hier der Grundaufbau eines jeden Services:

if ($argv[1] == 'install') {
	$x = win32_create_service(array(
		'service' => 'My_first_PHP_Service',
		'display' => 'My PHP Service',
		'params' => __FILE__ . ' run',
	));
	debug_zval_dump($x);
	exit;
} else if ($argv[1] == 'uninstall') {
	$x = win32_delete_service('My_first_PHP_Service');
	debug_zval_dump($x);
	exit;
} else if ($argv[1] != 'run') {
	die("bogus args, please use install/uninstall/run");
}

$x = win32_start_service_ctrl_dispatcher('My_first_PHP_Service');

while (WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {

	// here comes the code which will be executed
	// it should not last longer than 30sec if possible
	$someCode = new SomeCode();
	$someCode->start();

	usleep(500000);
}

Wir haben oben erstmal einige Zeilen, um den Dienst installieren und deinstallieren zu können. Das geht sehr einfach, man benötigt nur einen eindeutigen internen Dienstnamen (hier My_first_PHP_Service) und im Installationsfall eine Zeichenkette, die dann später angezeigt wird.

Aufgerufen mit dem Parameter „install“ wird der Dienst also installiert:service1

Dann können wir ihn starten, entweder von der Konsole oder aus der mmc:

service4

service3

Wie bereits als Kommentar geschrieben, sollte der Code in der Schleife nicht all zu lange laufen, damit der Dienst noch vernünftig gesteuert werden kann. Sollte der Code beispielsweise 5 Minuten laufen, und man versucht den Dienst zu beenden („net stop My_First_PHP_Service“ oder über die mmc), kommt nach ca. einer Minute die Nachricht:

service5

Windows wartet also nicht ewig darauf, dass sich der Dienst beendet. Im Falle des System-Shutdowns wird der Prozess dann zwangsweise hart gekillt, was wieder zu unserem Grundproblem führt. Zur Not muss man einfach die Arbeit in kleine Häppchen unterteilen und nacheinander aufrufen.

Die Deinstallation, ihr ahnt es schon, ist genauso einfach wie die Installation:

service2

Hier gibts noch einige Worte zur win32service extension vom Entwickler selbst:

Man kann natürlich nicht nur „normale“ Scripte bauen und als Dienst laufen lassen, man kann auch feine Dinge machen, indem man einen wirklichen „Dienst“ anbietet, der auf einem Port lauscht und zu dem man sich verbinden kann! Hier gibts Informationen zu Sockets unter PHP, und auch bald einen Artikel hier im Blog.

Falls ihr eure PHP-Scripte als Windows-Dienste laufen habt, würde mich interessieren, was diese Scripte so tun!

Written by Michael Kliewe

August 14th, 2009 at 7:53 pm

Posted in PHP

Tagged with , , , ,