CLI, the other SAPI

  • 5,087 views
Uploaded on

PHP isn't only used as a web-based scripting language, it can also be used on the command line. …

PHP isn't only used as a web-based scripting language, it can also be used on the command line.

This talks explains the benefits of command line PHP. Additionally, process control using CLI PHP is explained.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • you have a typo on frame 17. 'STDERR' should be 'STDOUT'
    Are you sure you want to
    Your message goes here
  • superpresentatie van Thijs ... alsof we iets anders verwacht hadden
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
5,087
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
39
Comments
2
Likes
6

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide












































































Transcript

  • 1. CLI, the other SAPI Using PHP on the command line in a Linux environment Thijs Feryn - thijs@combellgroup.com
  • 2. Who am I? • Thijs Feryn (http://blog.feryn.eu) • Support manager at COMBELL • Zend Certified PHP 5 developer • I love the LAMP stack • Working on my MySQL certification • Open-source contributor • Nerd/geek of some sort
  • 3. Who’s COMBELL?
  • 4. Who’s COMBELL? • Largest independent hoster in Belgium • Founded in 1999 (a decade of COMBELL) • Focus on premium/quality hosting • More than 25 000 customers • More than 100 000 domains • More than 20 000 websites • More than 1000 servers • More than 800 resellers Summarized: authorative partner for all hosted activity
  • 5. Who are you? • Who’s a developer? • Who’s a PHP developer? • Who has ever used the PHP CLI? • Who is used to working on Linux? • Who has experience with process forking?
  • 6. What’s up? 1. SAPI ... schmapi? (definition) 2. Common PHP SAPI’s (overview) 3. The CLI SAPI (how to use, possibilities, when to use) 4. Apache vs CLI (a comparison) 5. PHP binary options 6. CLI in action (some examples) 7. PCNTL == $fooDoo (the magic of process control) 8. Wake the daemons (putting it all together) 9. Q & A (the obligatory epilogue)
  • 7. SAPI ... schmapi? Definition Wikipedia says: “The Server Application Programming Interface (SAPI) is the generic term used to designate direct module interfaces to web server applications” In concreto: the SAPI is the way your server interacts with PHP
  • 8. Common SAPI’s Overview • Apache/Apache 2 • CGI • FastCGI • ISAPI • CLI • GTK
  • 9. Common SAPI’s Enabling the SAPI you need • CLI is included by default • Add the right parameter to enable the Apache SAPI when compiling from source ./configure --with-apxs=/location/of/your/apache/module
  • 10. The CLI SAPI Definition Php.net says: As of version 4.3.0, PHP supports a new SAPI type (Server Application Programming Interface) named CLI which means Command Line Interface. As the name implies, this SAPI type main focus is on developing shell (or desktop as well) applications with PHP. In Concreto: PHP scripts are no longer exclusively called via the web browser. Using CLI, PHP scripts can be executed from the command line of the server which offers a vast array of benefits
  • 11. The CLI SAPI When to use • In cron’s • For batches • Process control • Linux interactivity (e.g.: pipes)
  • 12. The CLI SAPI CLI 101 $p hp cli. • Each CLI script is called via the PHP binary php • Arguments can be passed • Arguments can be interpreted via special variables • Input can be passed via STDIN • Output can be returned via STDOUT • Errors can be returned via STDERR • I/O via pipes is possible
  • 13. The CLI SAPI CLI 101: arguments • Passing arguments $ php cli.php arg1 arg2 • Interpreting arguments via $_SERVER • $_SERVER[‘argc’] = counts the number of arguments • $_SERVER[‘argv’][0] = scriptname (cli.php) • $_SERVER[‘argv’][1] = first argument (arg1) • $_SERVER[‘argv’][2] = second argument (arg2)
  • 14. The CLI SAPI CLI 101: arguments If ‘register_argc_argv’ is enabled 2 extra local variables are registered: • $argc: counts the number of arguments • $argv: array which stores the arguments • $argv[0] = scriptname (cli.php) • $argv[1] = first argument (arg1) • $argv[2] = second argument (arg2)
  • 15. The CLI SAPI CLI 101: arguments & getopt() • Gets command line arguments & values based on an input variable containing all the options: • Individual characters (= flags, do not accept values) • Characters followed by colon (input value required) • Characters followed by 2 colons (input value optional) • Long options only work well in PHP 5.3 • Check out Zend_Console_Getopt, it has some nice features similar to getopt() $options = getopt(‘ab:c::’);
  • 16. The CLI SAPI CLI 101: input • Reading from STDIN by opening a stream $handle = fopen('php://stdin', 'r'); • Reading a single line from STDIN $stdin = trim(fgets(STDIN));
  • 17. The CLI SAPI CLI 101: output • Writing to STDOUT by opening a stream $handle = fopen('php://stdout', 'w'); • Writing a single line to STDERR fwrite(STDOUT,‘output’);
  • 18. The CLI SAPI CLI 101: errors • Writing to STDERR by opening a stream $handle = fopen('php://stderr', 'w'); • Writing a single line to STDERR fwrite(STDERR,‘error’);
  • 19. The CLI SAPI CLI 101: piping Using STDIN, STDOUT & STDERR streams you can easily benefit from the piping mechanisms in Linux to interact with other binaries $ cat input.ext | php myCliScript.php > output.ext $ php myCliScript.php | grep filterText > output.ext
  • 20. The CLI SAPI CLI 101: piping You can also combine it with arguments $ php myCliScript.php arg1 arg2 > output.ext $ cat input.ext | php myCliScript.php arg1 arg2 arg3 | grep filterText > output.ext
  • 21. Apache VS CLI State means everything Apache • HTTP is stateless a protocol • Limited interactivity • Sessions & cookies as workaround for these drawbacks • Execution timeouts • Limited packet size
  • 22. Apache VS CLI State means everything CLI • Controllable state • More interactivity • No (need for) sessions • No execution timeouts
  • 23. Apache VS CLI Ins & outs: input Apache CLI $_GET $_SERVER[‘argv’] $_POST $argv $_COOKIE $_ENV $_SESSION $_SERVER getopt() $_ENV STDIN
  • 24. Apache VS CLI Ins & outs: output Apache CLI HTTP output only STDOUT Limited packet size STDERR
  • 25. Apache VS CLI CLI usage, Apache mentality • Don’t use sessions or cookies, just use a local variables • Don’t “get” your input, “read” it • No execution timeouts • Bundled output (HTTP): in response message • Distributed output (CLI): via STDOUT. Available when needes
  • 26. Apache VS CLI CLI usage, Apache mentality • OVERHEAD ALERT: don’t use HTTP via crons (e.g. via lynx or wget), use the php binary. • CLI mode doesn’t change the CWD (current working directory). Be careful with path reference • Use “dirname(__FILE__)” • Use “chdir()”
  • 27. PHP binary options CLI options reference Usage: php [options] [-f] <file> [--] [args...] php [options] -r <code> [--] [args...] php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...] php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...] php [options] -- [args...] php [options] -a -a Run interactively -c <path>|<file> Look for php.ini file in this directory -n No php.ini file will be used -d foo[=bar] Define INI entry foo with value 'bar' -e Generate extended information for debugger/profiler -f <file> Parse and execute <file>. -h This help -i PHP information -l Syntax check only (lint) -m Show compiled in modules -r <code> Run PHP <code> without using script tags <?..?> -B <begin_code> Run PHP <begin_code> before processing input lines -R <code> Run PHP <code> for every input line -F <file> Parse and execute <file> for every input line -E <end_code> Run PHP <end_code> after processing all input lines -H Hide any passed arguments from external tools. -s Display colour syntax highlighted source. -v Version number -w Display source with stripped comments and whitespace. -z <file> Load Zend extension <file>. args... Arguments passed to script. Use -- args when first argument starts with - or script is read from stdin --ini Show configuration file names --rf <name> Show information about function <name>. --rc <name> Show information about class <name>. --re <name> Show information about extension <name>. --ri <name> Show configuration for extension <name>.
  • 28. PHP binary options Run code • Binary option: -r • Meaning: parse & run PHP code that is passed as an argument $ php -r “echo quot;Give me some outputquot;;” Give me some output Example $
  • 29. PHP binary options Interactive mode • Binary option: -a • Meaning: running PHP interactively in a true command line environment • Requirements: PHP compiled with readline support $ php -a $ php > echo quot;Give me some interactive outputquot;; Give me some interactive output Example $ php>
  • 30. PHP binary options Define configuration • Binary option: -d • Meaning: define INI configuration settings at runtime Example $ php -d max_execution_time=20 -r “echo ini_get(quot;max_execution_timequot;);” 20 $
  • 31. PHP binary options Lint check • Binary option: -l • Meaning: perform a “lint” check on a PHP file. Validates the syntax of a script. Errors are printed via STDOUT. Shell return codes are “0” or “1” • Notice: • Doesn’t work combined with the “-r” option. • Only checks for parsing errors & cannot retrieve fatal errors (e.g. undefined functions)
  • 32. PHP binary options List modules $ php -m • Binary option: -m [PHP Modules] xml • Meaning: prints all loaded PHP & Zend tokenizer standard modules session posix pcre overload mysql mbstring ctype Example [Zend Modules]
  • 33. PHP binary options Syntax highlighting • Binary option: -s • Meaning: format PHP code into highlighted HTML code • Notice: doesn’t work with the “-r” option. $ echo quot;<?php var_dump($_SERVER);quot; | php -s <code><span style=quot;color: #000000quot;> <span style=quot;color: #0000BBquot;>&lt;?php&nbsp;var_dump</span><span style=quot;color: #007700quot;>();<br /></span> </span> Example $
  • 34. PHP binary options Version information • Binary option: -v • Meaning: displays version information $ php -v PHP 5.2.4-2ubuntu5.3 with Suhosin-Patch 0.9.6.2 (cli) (built: Jul 23 2008 06:44:49) Copyright (c) 1997-2007 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans $ Example
  • 35. PHP binary options Function reflection • Binary option: --rf • Meaning: displays function API information • Requirements: PHP must be compiled with “Reflection” support $ php --rf var_dump Function [ <internal:standard> function var_dump ] { - Parameters [2] { Parameter #0 [ <required> $var ] Parameter #1 [ <optional> $... ] } } $ Example
  • 36. PHP binary options Class reflection • Binary option: --rc • Meaning: displays class API information • Requirements: PHP must be compiled with “Reflection” support
  • 37. PHP binary options Class reflection $ php --rc stdclass Class [ <internal> class stdClass ] { - Constants [0] { } - Static properties [0] { } - Static methods [0] { } - Properties [0] { } - Methods [0] { } } Example $
  • 38. CLI in action Read from STDIN + distributed output <?php /** * Read input from STDIN and print input with line numbers. * Quit when blank rule entered. */ $line = 0; do{ $line++; $input = trim(fgets(STDIN)); if(strlen($input) > 0){ echo quot;$line# $inputquot;.PHP_EOL; }else{ break; } }while (true); Code
  • 39. CLI in action Read from STDIN + distributed output $ php cli.php this 1# this is 2# is my 3# my output 4# output Output $
  • 40. CLI in action Read from STDIN + bundled output <?php /** * Read input from STDIN and print input with line numbers. * Quit when blank rule entered. * Bundle output and print at the end of the script. */ $line = 0; $output = ''; do{ $line++; $input = trim(fgets(STDIN)); if(strlen($input) > 0){ $output.= quot;$line# $inputquot;.PHP_EOL; }else{ break; } }while (true); echo $output; Code
  • 41. CLI in action Read from STDIN + bundled output $ php cli.php this is my output 1# this 2# is 3# my 4# output $ Output
  • 42. CLI in action Working with arguments <?php /** * Parse all arguments starting at index 1. * If format is quot;--keyquot; or quot;-keyquot;, parse key and assign quot;truequot; as value * If format is quot;--key=valuequot; or quot;-key=valuequot;, parse key and extract value * Else, value is argument, key is argument index */ for($i=1;$i<$argc;$i++) { if(preg_match('/^(-+)([a-zA-Z0-9_-]+)(=([a-zA-Z0-9_-])+)?$/',$argv[$i], $matches)){ $key = $matches[2]; if(array_key_exists(4,$matches)){ $value = $matches[4]; } else { $value = true; } } else { $key = $i; $value = $argv[$i]; } echo quot;Key: $key - Value: $valuequot;.PHP_EOL; Code }
  • 43. CLI in action Working with arguments $ php cli.php --flag1 -flag2 --option1=value1 -option2=value2 unNamedArgument Key: flag1 - Value: 1 Key: flag2 - Value: 1 Key: option1 - Value: 1 Key: option2 - Value: 2 Key: 5 - Value: unNamedArgument Output $
  • 44. CLI in action Shell binary #!/usr/bin/php <?php /** Code * Print the current time. * This binary directly uses the PHP binary. * When the script has execute permissions it can be called as quot;./cliquot; instead of quot;php cli.phpquot; */ echo quot;The current time is quot;.date('H:i:s').PHP_EOL; $ chmod +x ./cli $ Permissions $ ./cli The current time is 17:43:08 Call script + output $
  • 45. CLI in action Linux interaction & piping • Pass PHP code to binary using the “run” flag • Print 10 lines • Pipe output from PHP script as input for the “word count” binary • Add the “-l” flag to count the number of lines • Output 10 $ php -r 'for($i=0;$i<10;$i++) echo $i.PHP_EOL;' | wc -l 10 $
  • 46. CLI in action Using getopt() <?php $shortopts = quot;quot;; $shortopts .= quot;f:quot;; // Required value $shortopts .= quot;v::quot;; // Optional value $shortopts .= quot;abcquot;; // These options do not accept values $options = getopt($shortopts); Code var_dump($options); $ php cli.php -a -v -f value array(3) { [quot;aquot;]=> bool(false) [quot;vquot;]=> bool(false) } [quot;fquot;]=>string(5) quot;valuequot; Output
  • 47. PCNTL == $fooDoo The magic of process control Php.net says: Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment. Installation Add “--enable-pcntl” configuration option when compiling PHP
  • 48. PCNTL == $fooDoo Forking is not a culinary term • pcntl_fork() copies the program execution into a child process • Workload can be distributed between parent & child(s) via PID checking • Allow “multithreadish’ parallel execution by forking multiple child processes • Use a shared resource to define the workload (e.g.: file, array, DB, IPC, ...) Wikipedia says: In computing, when a process forks, it creates a copy of itself, which is called a quot;child process.quot; The original process is then called the quot;parent processquot;. More generally, a fork in a multithreading environment means that a thread of execution is duplicated, creating a child thread from the parent thread.
  • 49. PCNTL == $fooDoo PCNTL voodoo/$fooDoo • After forking, your logic is distributed in different PHP processes • Forking too many childs can cause performance issues • When using infinite loops, build in sleeps to avoid performance issues • Only use PCNTL in CLI mode • Be absolutely sure you master & control your child processes • Avoid zombie processes • Be able to kill your child processes at any time • Only kil your own processes Be very careful when forking child processes, because there are risks involved (hence the term $fooDoo)
  • 50. PCNTL == $fooDoo Forking example <?php $pid = pcntl_fork(); if ($pid == -1) { die('could not fork'); } else if ($pid) { echo quot;[parent] I am the parent process and my child process has PID $pidquot;.PHP_EOL; echo quot;[parent] Waiting for child terminationquot;.PHP_EOL; pcntl_wait($status); echo quot;[parent] Exitingquot;.PHP_EOL; } else { for($i=0;$i<10;$i++){ echo quot;[child] Loop $i, sleeping for a second ...quot;.PHP_EOL; sleep(1); } echo quot;[child] Exitingquot;.PHP_EOL; exit; }
  • 51. PCNTL == $fooDoo Multiple forking <?php for($i=0;$i<10;$i++){ $pid = pcntl_fork(); if ($pid == -1) { die('could not fork'); } else if ($pid == 0) { echo quot;[child] Child $i doing stuffquot;.PHP_EOL; sleep(1); echo quot;[child] Child $i exitingquot;.PHP_EOL; exit; } else { echo quot;[parent] Starting parent $iquot;.PHP_EOL; pcntl_wait($status); echo quot;[parent] Ending parent $iquot;.PHP_EOL; } }
  • 52. PCNTL == $fooDoo Multiple forking without waiting <?php echo quot;[parent] Starting parentquot;.PHP_EOL; for($i=0;$i<10;$i++){ $pid = pcntl_fork(); if ($pid == -1) { die('could not fork'); } else if ($pid == 0) { echo quot;[child] Child $i doing stuffquot;.PHP_EOL; sleep($i); echo quot;[child] Child $i exitingquot;.PHP_EOL; exit; } } echo quot;[parent] Ending parentquot;.PHP_EOL; exit;
  • 53. PCNTL == $fooDoo Signals Wikipedia says: A signal is a limited form of inter-process communication used in Unix, Unix-like, and other POSIX-compliant operating systems. Essentially it is an asynchronous notification sent to a process in order to notify it of an event that occurred. When a signal is sent to a process, the operating system interrupts the process' normal flow of execution. Execution can be interrupted during any non- atomic instruction. If the process has previously registered a signal handler, that routine is executed. Otherwise the default signal handler is executed.
  • 54. PCNTL == $fooDoo Signals • Communication between 2 processes • Process sends asynchronous notification of an event • Signal handlers can be used to execute custom logic • Otherwise default signal handlers
  • 55. PCNTL == $fooDoo Signals: SIGTERM • SIGTERM is used to terminate a process in a ‘nice’ way • Much more gentle than SIGKILL • Allows cleanup and closure of process • Issued via ‘kill’ (no kill -9)
  • 56. PCNTL == $fooDoo Signals: SIGINT • SIGINT is used to terminate a process via interruption • Stops program execution just like SIGTERM • Issued by a terminal (via CTRL+C)
  • 57. PCNTL == $fooDoo Signals: SIGCHLD • SIGCHLD is sent to the parent when a child process is terminated • Common when using process forking • SIGCHLD is by default ignored and a zombie process is created • Only sent when the parent issues a ‘wait’ call (avoids zombies)
  • 58. PCNTL == $fooDoo Signals: example of SIGTERM & SIGINT <?php declare(ticks = 1); function sig_handler($signo) { switch ($signo) { case SIGTERM: echo quot;SIGTERMquot;.PHP_EOL; exit(); break; case SIGINT: echo quot;SIGINTquot;.PHP_EOL; exit(); break; } } pcntl_signal(SIGTERM, quot;sig_handlerquot;); pcntl_signal(SIGINT, quot;sig_handlerquot;); sleep(100);
  • 59. PCNTL == $fooDoo Signals: example of SIGCHLD <?php declare(ticks = 1); $max=5; $simultaneous=0; $childId=0; function sig_handler($signo) { global $simultaneous,$childId; switch ($signo) { case SIGCHLD: $simultaneous--; echo quot;SIGCHLD received for child #$childIdquot;.PHP_EOL; echo quot;Decrementing to $simultaneousquot;.PHP_EOL; } } pcntl_signal(SIGCHLD, quot;sig_handlerquot;);
  • 60. PCNTL == $fooDoo Signals: example of SIGCHLD for ($childId=0;$childId<10;$childId++){ $pid=pcntl_fork(); if ($pid == -1) { die(quot;could not forkquot;); } else if ($pid) { if ( $simultaneous >= $max ){ pcntl_wait($status); } else { $simultaneous++; echo quot;Increment to $simultaneousquot;.PHP_EOL; } } else { echo quot;Starting new child #$childId quot;.PHP_EOL; echo quot;Now we de have $simultaneous simultaneous child processesquot;.PHP_EOL; sleep(rand(3,5)); exit; } }
  • 61. PCNTL == $fooDoo POSIX functions Wikipedia says: POSIX or quot;Portable Operating System Interface for Unixquot; is the collective name of a family of related standards specified by the IEEE to define the application programming interface (API), along with shell and utilities interfaces for software compatible with variants of the Unix operating system, although the standard can apply to any operating system.
  • 62. PCNTL == $fooDoo POSIX functions In PHP: POSIX functions in PHP allow you to interact with the POSIX interface of the operating system. For process control functions we mainly use POSIX to retrieve PID information and terminate/kill processes
  • 63. PCNTL == $fooDoo POSIX functions posix_getpid() • Determine the PID of the current process • pcntl_fork() returnthe child process process is the same as posix_getpid() for value for the parent posix_getppid() • Determine the PID of the parent of the process • posix_getpid() valuethe childparent process is the same as posix_getppid() for for the process • posix_getppid() value for the parent process is the PID of the bash session
  • 64. PCNTL == $fooDoo POSIX functions: example of posix_getpid() & posix_getppid() <?php echo quot;[prefork] PID POSIX: quot;.posix_getpid().quot;, parent PID: quot;.posix_getppid().PHP_EOL; for($i=0;$i<3;$i++){ $pid = pcntl_fork(); if ($pid == -1) { die('could not fork'); } else if ($pid == 0) { echo quot;[child] ID: $i, PID: quot;.posix_getpid().quot;, parent PID: quot;.posix_getppid().PHP_EOL; exit; } else { echo quot;[parent] PID : quot;.posix_getpid().quot;, parent PID: quot;.posix_getppid().PHP_EOL; pcntl_wait($status); } }
  • 65. PCNTL == $fooDoo POSIX functions posix_kill() • Send a signal to a certain process • posix_kill($pid,0): gets PID status • true: pid exists • false: pid no longer exists • posix_kill($pid,9) or posix_kill($pid,SIGKILL): kill a process • posix_kill($pid,15) or posix_kill($pid,SIGTERM): terminate a process
  • 66. PCNTL == $fooDoo POSIX functions: example of posix_kill() <?php $pid=pcntl_fork(); if ($pid == -1) { die(quot;could not forkquot;); } else if ($pid) { $exists = posix_kill($pid,0)?'still':'no longer'; echo quot;[parent] Child process $pid $exists existsquot;.PHP_EOL; echo quot;[parent] Killing child process $pidquot;.PHP_EOL; posix_kill($pid,SIGKILL); echo quot;[parent] Child process $pid killedquot;.PHP_EOL; pcntl_wait($status); $exists = posix_kill($pid,0)?'still':'no longer'; echo quot;[parent] Child process $pid $exists existsquot;.PHP_EOL; } else { while(true){ sleep(100); } exit; }
  • 67. Wake the daemons The daemon (1) #!/usr/bin/php <?php date_default_timezone_set('Europe/Brussels'); $options = getopt('p:d:'); /** * Determine pidfile */ if(!array_key_exists('p',$options)){ die('No pidfile specified'.PHP_EOL); } define('PIDFILE',$options['p']); /** * Determine datadir */ if(!array_key_exists('d',$options)){ die('No data directory specified'.PHP_EOL); }else{ if(!is_dir($options['d'])){ die('Data directory does not exist'.PHP_EOL); } } define('DATADIR',$options['d']);
  • 68. Wake the daemons The daemon (2) /** * Delete pidfile on startup */ if(file_exists(PIDFILE)){ unlink(PIDFILE); } /** * Delete pidfile after SIGINT or SIGTERM */ function signal_handler($sig){ if(file_exists(PIDFILE)){ unlink(PIDFILE); } } /** * Set signal handler */ pcntl_signal(SIGINT,'signal_handler'); pcntl_signal(SIGTERM,'signal_handler');
  • 69. Wake the daemons The daemon (3) /* * Setup daemon */ $pid=pcntl_fork(); if ($pid == -1) { die(quot;could not forkquot;.PHP_EOL); } else if ($pid) { exit; } /** * System settings */ posix_setsid(); chdir(quot;/quot;); /** * Store PID */ $handle = fopen(PIDFILE,'w+'); fwrite($handle,posix_getpid()); fclose($handle);
  • 70. Wake the daemons The daemon (4) /** * Perform daemon logic */ while(true){ $handle = fopen(DATADIR.'/thijs_'.date('YmdHis'),'w+'); fwrite($handle,'abc123'); fclose($handle); sleep(10); }
  • 71. Wake the daemons The startup script (1) #!/usr/bin/php <?php /** * Count args */ if($argc < 2){ die(quot;tUsage: php quot;.basename(__FILE__).quot; start|stop|status|restartquot;.PHP_EOL); } /** * Init params */ define('PIDFILE','/tmp/daemon.pid'); define('DAEMONBIN','/home/thijs/test/pcntl/daemon.php'); define('DATADIR','/tmp'); function startDaemon() { echo quot;Starting daemonquot;.PHP_EOL; $start = DAEMONBIN.' -p'.PIDFILE.' -d '.DATADIR; passthru($start); }
  • 72. Wake the daemons The startup script (2) function stopDaemon() { if(file_exists(PIDFILE)){ $pid = (int)trim(file_get_contents(PIDFILE)); if(posix_kill($pid,0)){ if(posix_kill($pid,SIGKILL)){ echo 'Daemon stopped'.PHP_EOL; } else { echo 'Error stopping daemon'.PHP_EOL; } } else { echo 'Daemon no longer active, deleting pidfile'.PHP_EOL; } unlink(PIDFILE); } else { echo 'Daemon stopped'.PHP_EOL; } }
  • 73. Wake the daemons The startup script (3) function statusDaemon() { if(file_exists(PIDFILE)){ $pid = (int)trim(file_get_contents(PIDFILE)); if(posix_kill($pid,0)){ echo'Daemon is running'.PHP_EOL; } else { echo 'Daemon no longer active, but pidfile still exists'.PHP_EOL; } } else { echo'Daemon is not running'.PHP_EOL; } }
  • 74. Wake the daemons The startup script (4) switch ($argv[1]){ case 'start': startDaemon(); break; case 'stop': stopDaemon(); break; case 'status': statusDaemon(); break; case 'restart': stopDaemon(); sleep(2); startDaemon(); break; default: die(quot;tUsage: quot;.basename(__FILE__).quot; start | stop | status | restartquot;.PHP_EOL); }
  • 75. Q&A
  • 76. THANKS !