SlideShare a Scribd company logo
1 of 76
Download to read offline
CLI, the other SAPI
Using PHP on the command line in a Linux
              environment
       Thijs Feryn - thijs@combellgroup.com
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
Who’s COMBELL?
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
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?
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)
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
Common SAPI’s
Overview

       • Apache/Apache 2
       • CGI
       • FastCGI
       • ISAPI
       • CLI
       • GTK
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
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
The CLI SAPI
 When to use

• In cron’s
• For batches
• Process control
• Linux interactivity (e.g.: pipes)
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
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)
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)
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::’);
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));
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’);
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’);
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
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
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
Apache VS CLI
 State means everything


                          CLI
• Controllable state
• More interactivity
• No (need for) sessions
• No execution timeouts
Apache VS CLI
Ins & outs: input
        Apache                  CLI
    $_GET
                     $_SERVER[‘argv’]
    $_POST
                     $argv
    $_COOKIE
                     $_ENV
    $_SESSION
    $_SERVER         getopt()
    $_ENV            STDIN
Apache VS CLI
Ins & outs: output

       Apache                   CLI
 HTTP output only      STDOUT
 Limited packet size   STDERR
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
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()”
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>.
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
   $
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>
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
   $
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)
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]
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
 $
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
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
PHP binary options
          Class reflection



• Binary option: --rc
• Meaning: displays class API information
• Requirements: PHP must be compiled with “Reflection”
  support
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
$
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
CLI in action
Read from STDIN + distributed output




 $ php cli.php

 this
 1# this
 is
 2# is
 my
 3# my
 output
 4# output                             Output
 $
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
CLI in action
Read from STDIN + bundled output



$ php cli.php

this
is
my
output

1# this
2# is
3# my
4# output

$                                  Output
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
}
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
$
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
  $
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

   $
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
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
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.
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)
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;
}
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;
	 }
}
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;
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.
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
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)
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)
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)
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);
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;);
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;
	 }
}
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.
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
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
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);
	 }
}
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
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;
}
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']);
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');
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);
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);	
}
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);
}
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;	
	 }	
}
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;	
	 }	
}
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);
}
Q&A
THANKS !

More Related Content

What's hot

Last train to php 7
Last train to php 7Last train to php 7
Last train to php 7Damien Seguy
 
PHP 7 Crash Course - php[world] 2015
PHP 7 Crash Course - php[world] 2015PHP 7 Crash Course - php[world] 2015
PHP 7 Crash Course - php[world] 2015Colin O'Dell
 
Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Wim Godden
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4Wim Godden
 
Php 7 hhvm and co
Php 7 hhvm and coPhp 7 hhvm and co
Php 7 hhvm and coPierre Joye
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPGuilherme Blanco
 
Yapc::NA::2009 - Command Line Perl
Yapc::NA::2009 - Command Line PerlYapc::NA::2009 - Command Line Perl
Yapc::NA::2009 - Command Line PerlBruce Gray
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13julien pauli
 
Php7 HHVM and co
Php7 HHVM and coPhp7 HHVM and co
Php7 HHVM and coweltling
 
2021.laravelconf.tw.slides2
2021.laravelconf.tw.slides22021.laravelconf.tw.slides2
2021.laravelconf.tw.slides2LiviaLiaoFontech
 
Static Analysis of PHP Code – IPC Berlin 2016
Static Analysis of PHP Code – IPC Berlin 2016Static Analysis of PHP Code – IPC Berlin 2016
Static Analysis of PHP Code – IPC Berlin 2016Rouven Weßling
 
A bridge between php and ruby
A bridge between php and ruby A bridge between php and ruby
A bridge between php and ruby do_aki
 
When symfony met promises
When symfony met promises When symfony met promises
When symfony met promises Marc Morera
 
Clear php reference
Clear php referenceClear php reference
Clear php referenceDamien Seguy
 
typemap in Perl/XS
typemap in Perl/XS  typemap in Perl/XS
typemap in Perl/XS charsbar
 
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)Mark Niebergall
 

What's hot (20)

Last train to php 7
Last train to php 7Last train to php 7
Last train to php 7
 
PHP7 is coming
PHP7 is comingPHP7 is coming
PHP7 is coming
 
Hacking with hhvm
Hacking with hhvmHacking with hhvm
Hacking with hhvm
 
PHP 7 Crash Course - php[world] 2015
PHP 7 Crash Course - php[world] 2015PHP 7 Crash Course - php[world] 2015
PHP 7 Crash Course - php[world] 2015
 
Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4
 
Php 7 hhvm and co
Php 7 hhvm and coPhp 7 hhvm and co
Php 7 hhvm and co
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
Yapc::NA::2009 - Command Line Perl
Yapc::NA::2009 - Command Line PerlYapc::NA::2009 - Command Line Perl
Yapc::NA::2009 - Command Line Perl
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
 
Php7 HHVM and co
Php7 HHVM and coPhp7 HHVM and co
Php7 HHVM and co
 
2021.laravelconf.tw.slides2
2021.laravelconf.tw.slides22021.laravelconf.tw.slides2
2021.laravelconf.tw.slides2
 
Static Analysis of PHP Code – IPC Berlin 2016
Static Analysis of PHP Code – IPC Berlin 2016Static Analysis of PHP Code – IPC Berlin 2016
Static Analysis of PHP Code – IPC Berlin 2016
 
A bridge between php and ruby
A bridge between php and ruby A bridge between php and ruby
A bridge between php and ruby
 
When symfony met promises
When symfony met promises When symfony met promises
When symfony met promises
 
The state of DI - DPC12
The state of DI - DPC12The state of DI - DPC12
The state of DI - DPC12
 
Clear php reference
Clear php referenceClear php reference
Clear php reference
 
typemap in Perl/XS
typemap in Perl/XS  typemap in Perl/XS
typemap in Perl/XS
 
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
 

Viewers also liked

Educational technology 2015 1
Educational technology 2015 1Educational technology 2015 1
Educational technology 2015 1Gilmar Mattos
 
Banish Your Inner Critic
Banish Your Inner CriticBanish Your Inner Critic
Banish Your Inner CriticDenise Jacobs
 
Access formal evaluation
Access   formal evaluationAccess   formal evaluation
Access formal evaluationGilmar Mattos
 
Staff Housing
Staff HousingStaff Housing
Staff Housingezran
 
I Giovani Di Federmanager 2008
I Giovani Di Federmanager 2008I Giovani Di Federmanager 2008
I Giovani Di Federmanager 2008guest1c2ad5
 
Banish Your Inner Critic - Cascade SF
Banish Your Inner Critic - Cascade SFBanish Your Inner Critic - Cascade SF
Banish Your Inner Critic - Cascade SFDenise Jacobs
 
The Creativity (R)Evolution - UX Week 2014
The Creativity (R)Evolution -  UX Week 2014The Creativity (R)Evolution -  UX Week 2014
The Creativity (R)Evolution - UX Week 2014Denise Jacobs
 
InterAct Book Summit: Preventing Information Overload
InterAct Book Summit: Preventing Information OverloadInterAct Book Summit: Preventing Information Overload
InterAct Book Summit: Preventing Information OverloadDenise Jacobs
 
CARLOS POLO
CARLOS POLOCARLOS POLO
CARLOS POLOlavelada
 
University Slideshow
University SlideshowUniversity Slideshow
University Slideshowguestca3ad7
 
Adv 2 Teens Inversions
Adv 2 Teens InversionsAdv 2 Teens Inversions
Adv 2 Teens InversionsGilmar Mattos
 
Banish Your Inner Critic - Facebook Design Lecture Series
Banish Your Inner Critic - Facebook Design Lecture SeriesBanish Your Inner Critic - Facebook Design Lecture Series
Banish Your Inner Critic - Facebook Design Lecture SeriesDenise Jacobs
 
Can The Afrosphere Survive the Age of Obama?
Can The Afrosphere Survive the Age of Obama?Can The Afrosphere Survive the Age of Obama?
Can The Afrosphere Survive the Age of Obama?Denise Jacobs
 
Technology And Education
Technology And EducationTechnology And Education
Technology And Educationcoppusc
 
Find Your (Shameless) Spark
Find Your (Shameless) SparkFind Your (Shameless) Spark
Find Your (Shameless) SparkDenise Jacobs
 
InnoGage EduWeb Conference UGC - Tapping The Power
InnoGage   EduWeb Conference UGC - Tapping The PowerInnoGage   EduWeb Conference UGC - Tapping The Power
InnoGage EduWeb Conference UGC - Tapping The PowerTom Williams
 
The Creativity Imperative - Work Life Congress 2015
The Creativity Imperative - Work Life Congress 2015The Creativity Imperative - Work Life Congress 2015
The Creativity Imperative - Work Life Congress 2015Denise Jacobs
 
Natural River Bed - Dry
Natural River Bed - DryNatural River Bed - Dry
Natural River Bed - DryDaniel Peabody
 

Viewers also liked (20)

Educational technology 2015 1
Educational technology 2015 1Educational technology 2015 1
Educational technology 2015 1
 
Banish Your Inner Critic
Banish Your Inner CriticBanish Your Inner Critic
Banish Your Inner Critic
 
Access formal evaluation
Access   formal evaluationAccess   formal evaluation
Access formal evaluation
 
Staff Housing
Staff HousingStaff Housing
Staff Housing
 
I Giovani Di Federmanager 2008
I Giovani Di Federmanager 2008I Giovani Di Federmanager 2008
I Giovani Di Federmanager 2008
 
Banish Your Inner Critic - Cascade SF
Banish Your Inner Critic - Cascade SFBanish Your Inner Critic - Cascade SF
Banish Your Inner Critic - Cascade SF
 
The Creativity (R)Evolution - UX Week 2014
The Creativity (R)Evolution -  UX Week 2014The Creativity (R)Evolution -  UX Week 2014
The Creativity (R)Evolution - UX Week 2014
 
InterAct Book Summit: Preventing Information Overload
InterAct Book Summit: Preventing Information OverloadInterAct Book Summit: Preventing Information Overload
InterAct Book Summit: Preventing Information Overload
 
1st Fam Gath
1st Fam Gath1st Fam Gath
1st Fam Gath
 
CARLOS POLO
CARLOS POLOCARLOS POLO
CARLOS POLO
 
University Slideshow
University SlideshowUniversity Slideshow
University Slideshow
 
Adv 2 Teens Inversions
Adv 2 Teens InversionsAdv 2 Teens Inversions
Adv 2 Teens Inversions
 
Deft v7
Deft v7Deft v7
Deft v7
 
Banish Your Inner Critic - Facebook Design Lecture Series
Banish Your Inner Critic - Facebook Design Lecture SeriesBanish Your Inner Critic - Facebook Design Lecture Series
Banish Your Inner Critic - Facebook Design Lecture Series
 
Can The Afrosphere Survive the Age of Obama?
Can The Afrosphere Survive the Age of Obama?Can The Afrosphere Survive the Age of Obama?
Can The Afrosphere Survive the Age of Obama?
 
Technology And Education
Technology And EducationTechnology And Education
Technology And Education
 
Find Your (Shameless) Spark
Find Your (Shameless) SparkFind Your (Shameless) Spark
Find Your (Shameless) Spark
 
InnoGage EduWeb Conference UGC - Tapping The Power
InnoGage   EduWeb Conference UGC - Tapping The PowerInnoGage   EduWeb Conference UGC - Tapping The Power
InnoGage EduWeb Conference UGC - Tapping The Power
 
The Creativity Imperative - Work Life Congress 2015
The Creativity Imperative - Work Life Congress 2015The Creativity Imperative - Work Life Congress 2015
The Creativity Imperative - Work Life Congress 2015
 
Natural River Bed - Dry
Natural River Bed - DryNatural River Bed - Dry
Natural River Bed - Dry
 

Similar to CLI, the other SAPI

Cli the other SAPI confoo11
Cli the other SAPI confoo11Cli the other SAPI confoo11
Cli the other SAPI confoo11Combell NV
 
CLI, the other SAPI phpnw11
CLI, the other SAPI phpnw11CLI, the other SAPI phpnw11
CLI, the other SAPI phpnw11Combell NV
 
Prepare for PHP Test Fest 2009
Prepare for PHP Test Fest 2009Prepare for PHP Test Fest 2009
Prepare for PHP Test Fest 2009PHPBelgium
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)Muhamad Al Imran
 
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)Muhamad Al Imran
 
DevOps in PHP environment
DevOps in PHP environmentDevOps in PHP environment
DevOps in PHP environmentEvaldo Felipe
 
Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!Jeff Jones
 
php & performance
 php & performance php & performance
php & performancesimon8410
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckrICh morrow
 

Similar to CLI, the other SAPI (20)

Cli the other SAPI confoo11
Cli the other SAPI confoo11Cli the other SAPI confoo11
Cli the other SAPI confoo11
 
CLI, the other SAPI phpnw11
CLI, the other SAPI phpnw11CLI, the other SAPI phpnw11
CLI, the other SAPI phpnw11
 
Prepare for PHP Test Fest 2009
Prepare for PHP Test Fest 2009Prepare for PHP Test Fest 2009
Prepare for PHP Test Fest 2009
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Lecture8
Lecture8Lecture8
Lecture8
 
Laravel level 0 (introduction)
Laravel level 0 (introduction)Laravel level 0 (introduction)
Laravel level 0 (introduction)
 
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
 
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
 
Php i basic chapter 3
Php i basic chapter 3Php i basic chapter 3
Php i basic chapter 3
 
DevOps in PHP environment
DevOps in PHP environmentDevOps in PHP environment
DevOps in PHP environment
 
PHP
PHPPHP
PHP
 
Api Design
Api DesignApi Design
Api Design
 
Php.ppt
Php.pptPhp.ppt
Php.ppt
 
Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!
 
CGI Presentation
CGI PresentationCGI Presentation
CGI Presentation
 
Introduction to php basics
Introduction to php   basicsIntroduction to php   basics
Introduction to php basics
 
php 1
php 1php 1
php 1
 
php & performance
 php & performance php & performance
php & performance
 
PHP
PHPPHP
PHP
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course Deck
 

More from Combell NV

Play it extra safe! Kies een goede cyberverzekering
Play it extra safe! Kies een goede cyberverzekeringPlay it extra safe! Kies een goede cyberverzekering
Play it extra safe! Kies een goede cyberverzekeringCombell NV
 
Hoe gebruik je het resellerplatform als partner van Combell
Hoe gebruik je het resellerplatform als partner van CombellHoe gebruik je het resellerplatform als partner van Combell
Hoe gebruik je het resellerplatform als partner van CombellCombell NV
 
Managed WordPress bij Combell – wat doet dat precies?
Managed WordPress bij Combell – wat doet dat precies?Managed WordPress bij Combell – wat doet dat precies?
Managed WordPress bij Combell – wat doet dat precies?Combell NV
 
Back-ups: Hoe ze je kunnen redden van een cyberaanval
Back-ups: Hoe ze je kunnen redden van een cyberaanvalBack-ups: Hoe ze je kunnen redden van een cyberaanval
Back-ups: Hoe ze je kunnen redden van een cyberaanvalCombell NV
 
Cyberaanvallen: Overzicht, gevolgen en beveiligingstips
Cyberaanvallen: Overzicht, gevolgen en beveiligingstipsCyberaanvallen: Overzicht, gevolgen en beveiligingstips
Cyberaanvallen: Overzicht, gevolgen en beveiligingstipsCombell NV
 
Hoe gebruik je het resellerplatform als partner van Combell
Hoe gebruik je het resellerplatform als partner van CombellHoe gebruik je het resellerplatform als partner van Combell
Hoe gebruik je het resellerplatform als partner van CombellCombell NV
 
Hoe laat je jouw website scoren in zoekmachines zoals Google
Hoe laat je jouw website scoren in zoekmachines zoals GoogleHoe laat je jouw website scoren in zoekmachines zoals Google
Hoe laat je jouw website scoren in zoekmachines zoals GoogleCombell NV
 
Een webshop bouwen in WooCommerce – advanced sessie
Een webshop bouwen in WooCommerce – advanced sessieEen webshop bouwen in WooCommerce – advanced sessie
Een webshop bouwen in WooCommerce – advanced sessieCombell NV
 
Hoe start je een webshop met WordPress / WooCommerce
Hoe start je een webshop met WordPress / WooCommerceHoe start je een webshop met WordPress / WooCommerce
Hoe start je een webshop met WordPress / WooCommerceCombell NV
 
Keeping the cloud in check cvodmd
Keeping the cloud in check cvodmdKeeping the cloud in check cvodmd
Keeping the cloud in check cvodmdCombell NV
 
Hybrid cloud wiskyweb2012
Hybrid cloud wiskyweb2012Hybrid cloud wiskyweb2012
Hybrid cloud wiskyweb2012Combell NV
 
2012 03-27 developers e-commercedag presentatie5 ssl
2012 03-27 developers e-commercedag presentatie5 ssl2012 03-27 developers e-commercedag presentatie5 ssl
2012 03-27 developers e-commercedag presentatie5 sslCombell NV
 
2012 03-27 developers e-commercedag presentatie2 drupal
2012 03-27 developers e-commercedag presentatie2 drupal2012 03-27 developers e-commercedag presentatie2 drupal
2012 03-27 developers e-commercedag presentatie2 drupalCombell NV
 
2012 03-27 developers e-commercedag presentatie1 magento
2012 03-27 developers e-commercedag presentatie1 magento2012 03-27 developers e-commercedag presentatie1 magento
2012 03-27 developers e-commercedag presentatie1 magentoCombell NV
 
2012 03-27 developers e-commercedag presentatie4 ogone
2012 03-27 developers e-commercedag presentatie4 ogone2012 03-27 developers e-commercedag presentatie4 ogone
2012 03-27 developers e-commercedag presentatie4 ogoneCombell NV
 
10 doe-het-zelf tips om aan e-commerce te doen
10 doe-het-zelf tips om aan e-commerce te doen10 doe-het-zelf tips om aan e-commerce te doen
10 doe-het-zelf tips om aan e-commerce te doenCombell NV
 
Develop and deploy using Hybrid Cloud Strategies confoo2012
Develop and deploy using Hybrid Cloud Strategies confoo2012Develop and deploy using Hybrid Cloud Strategies confoo2012
Develop and deploy using Hybrid Cloud Strategies confoo2012Combell NV
 
Php through the eyes of a hoster confoo
Php through the eyes of a hoster confooPhp through the eyes of a hoster confoo
Php through the eyes of a hoster confooCombell NV
 
Hybrid Cloud PHPUK2012
Hybrid Cloud PHPUK2012Hybrid Cloud PHPUK2012
Hybrid Cloud PHPUK2012Combell NV
 
2012 02-07 sql denali presentatie microsoft
2012 02-07 sql denali presentatie microsoft2012 02-07 sql denali presentatie microsoft
2012 02-07 sql denali presentatie microsoftCombell NV
 

More from Combell NV (20)

Play it extra safe! Kies een goede cyberverzekering
Play it extra safe! Kies een goede cyberverzekeringPlay it extra safe! Kies een goede cyberverzekering
Play it extra safe! Kies een goede cyberverzekering
 
Hoe gebruik je het resellerplatform als partner van Combell
Hoe gebruik je het resellerplatform als partner van CombellHoe gebruik je het resellerplatform als partner van Combell
Hoe gebruik je het resellerplatform als partner van Combell
 
Managed WordPress bij Combell – wat doet dat precies?
Managed WordPress bij Combell – wat doet dat precies?Managed WordPress bij Combell – wat doet dat precies?
Managed WordPress bij Combell – wat doet dat precies?
 
Back-ups: Hoe ze je kunnen redden van een cyberaanval
Back-ups: Hoe ze je kunnen redden van een cyberaanvalBack-ups: Hoe ze je kunnen redden van een cyberaanval
Back-ups: Hoe ze je kunnen redden van een cyberaanval
 
Cyberaanvallen: Overzicht, gevolgen en beveiligingstips
Cyberaanvallen: Overzicht, gevolgen en beveiligingstipsCyberaanvallen: Overzicht, gevolgen en beveiligingstips
Cyberaanvallen: Overzicht, gevolgen en beveiligingstips
 
Hoe gebruik je het resellerplatform als partner van Combell
Hoe gebruik je het resellerplatform als partner van CombellHoe gebruik je het resellerplatform als partner van Combell
Hoe gebruik je het resellerplatform als partner van Combell
 
Hoe laat je jouw website scoren in zoekmachines zoals Google
Hoe laat je jouw website scoren in zoekmachines zoals GoogleHoe laat je jouw website scoren in zoekmachines zoals Google
Hoe laat je jouw website scoren in zoekmachines zoals Google
 
Een webshop bouwen in WooCommerce – advanced sessie
Een webshop bouwen in WooCommerce – advanced sessieEen webshop bouwen in WooCommerce – advanced sessie
Een webshop bouwen in WooCommerce – advanced sessie
 
Hoe start je een webshop met WordPress / WooCommerce
Hoe start je een webshop met WordPress / WooCommerceHoe start je een webshop met WordPress / WooCommerce
Hoe start je een webshop met WordPress / WooCommerce
 
Keeping the cloud in check cvodmd
Keeping the cloud in check cvodmdKeeping the cloud in check cvodmd
Keeping the cloud in check cvodmd
 
Hybrid cloud wiskyweb2012
Hybrid cloud wiskyweb2012Hybrid cloud wiskyweb2012
Hybrid cloud wiskyweb2012
 
2012 03-27 developers e-commercedag presentatie5 ssl
2012 03-27 developers e-commercedag presentatie5 ssl2012 03-27 developers e-commercedag presentatie5 ssl
2012 03-27 developers e-commercedag presentatie5 ssl
 
2012 03-27 developers e-commercedag presentatie2 drupal
2012 03-27 developers e-commercedag presentatie2 drupal2012 03-27 developers e-commercedag presentatie2 drupal
2012 03-27 developers e-commercedag presentatie2 drupal
 
2012 03-27 developers e-commercedag presentatie1 magento
2012 03-27 developers e-commercedag presentatie1 magento2012 03-27 developers e-commercedag presentatie1 magento
2012 03-27 developers e-commercedag presentatie1 magento
 
2012 03-27 developers e-commercedag presentatie4 ogone
2012 03-27 developers e-commercedag presentatie4 ogone2012 03-27 developers e-commercedag presentatie4 ogone
2012 03-27 developers e-commercedag presentatie4 ogone
 
10 doe-het-zelf tips om aan e-commerce te doen
10 doe-het-zelf tips om aan e-commerce te doen10 doe-het-zelf tips om aan e-commerce te doen
10 doe-het-zelf tips om aan e-commerce te doen
 
Develop and deploy using Hybrid Cloud Strategies confoo2012
Develop and deploy using Hybrid Cloud Strategies confoo2012Develop and deploy using Hybrid Cloud Strategies confoo2012
Develop and deploy using Hybrid Cloud Strategies confoo2012
 
Php through the eyes of a hoster confoo
Php through the eyes of a hoster confooPhp through the eyes of a hoster confoo
Php through the eyes of a hoster confoo
 
Hybrid Cloud PHPUK2012
Hybrid Cloud PHPUK2012Hybrid Cloud PHPUK2012
Hybrid Cloud PHPUK2012
 
2012 02-07 sql denali presentatie microsoft
2012 02-07 sql denali presentatie microsoft2012 02-07 sql denali presentatie microsoft
2012 02-07 sql denali presentatie microsoft
 

Recently uploaded

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 

Recently uploaded (20)

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 

CLI, the other SAPI

  • 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
  • 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

Editor's Notes