Cli the other sapi pbc11

  • 1,113 views
Uploaded on

Slides for my pbc11 talks in Barcelona

Slides for my pbc11 talks in Barcelona

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,113
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
24
Comments
0
Likes
2

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 PHPBarcelona  Conference Friday  October  28th  2011 Barcelona,  Spain php Thijs  Feryn Evangelist +32  (0)9  218  79  06 thijs@combellgroup.com
  • 2. About  me I’m  an  Evangelist  at  Combell
  • 3. About  me I’m  a  board  member  at  PHPBenelux
  • 4. Follow  me  on  Twi+er:  @ThijsFerynGive  me  feedback:  h+p://joind.in/4323
  • 5. SAPI? The  way  you  interact  with  PHP
  • 6. Common  SAPIs
  • 7. Common  SAPIs • Apache/Apache  2 • FPM • FastCGI • ISAPI • CLI • GTK
  • 8. The  CLI  SAPIPHP  script  execuYon  via  the  command  line  interface
  • 9. When  to  use
  • 10. When  to  use• In  crons• For  batch  tasks• For  worker  processes• Daemons• Process  control• InteracYon  with  other  binaries
  • 11. CLI 101
  • 12. CLI 101The PHP binaryPassing argumentsReading from STDINI/O with pipes
  • 13. CLI 101Invoking a script with the PHP binaryphp  file.php
  • 14. CLI 101 Passing argumentsphp  file.php  arg1  arg2
  • 15. CLI 101 interpreting arguments<?phpecho "Number of arguments {$argc}n";foreach($argv as $key=>$argument){    echo "Argument # {$key}: {$argument}n"; }
  • 16. CLI 101 interpreting arguments Argument   Argument   count array<?phpecho "Number of arguments {$argc}n";foreach($argv as $key=>$argument){    echo "Argument # {$key}: {$argument}n"; }
  • 17. CLI 101 The   PHP  file  is  an  interpreting arguments argument  too$  php  args.php  arg1  arg2Number  of  arguments  3Argument  #  0:  args.phpArgument  #  1:  arg1Argument  #  2:  arg2$
  • 18. CLI 101 interpreting arguments$_SERVER[‘argc’] $argc$_SERVER[‘argv’] $argv !!! register_argc_argv !!!
  • 19. CLI 101 getopt<?php$arguments = getopt(ab:c::);var_dump($arguments);
  • 20. CLI 101 getopt OpYonal   Flag   (no  value) value<?php$arguments = getopt(ab:c::);var_dump($arguments); Required   value
  • 21. CLI 101php  getopt.php  -­‐a  -­‐b  2  -­‐c3array(3)  {    ["a"]=> No      bool(false)    ["b"]=> spacing  for      string(1)  "2" opYonal      ["c"]=> arguments    string(1)  "3"}
  • 22. CLI 101 getopt: longopts<?php$arguments = getopt(,array(arg1,arg2:,arg3::));var_dump($arguments);
  • 23. CLI 101php  getopt2.php  -­‐-­‐arg1  -­‐-­‐arg2  123  -­‐-­‐arg3=xarray(3)  {    ["arg1"]=>    bool(false) Mind      ["arg2"]=> the  “=”  sign    string(3)  "123"    ["arg3"]=>    string(1)  "x"}
  • 24. CLI 101 REading From STDIN<?php$handle = fopen(php://stdin,r);while(!feof($handle)){    $line = trim(fgets($handle));    if(strlen($line) > 0){        echo strrev($line).PHP_EOL;    }}fclose($handle);
  • 25. CLI 101$  cat  test.txt  |  php  stdin.php  enOowTeerhT$
  • 26. CLI 101$  cat  test.txt  |  php  stdin.php  enOowT Output   Convert  eerhT$ file output  to   input  with   pipes
  • 27. Comparing  the  Apache  &  CLI  SAPI
  • 28. Comparing  the  Apache  &  CLI  SAPI Web  based  SAPI’s• HTTP  is  a  stateless  protocol• Request/response  based• Limited  interacYon• Sessions  &  cookies  as  workaround• ExecuYon  Ymeouts• Limited  request/response  size
  • 29. Comparing  the  Apache  &  CLI  SAPI CLI  SAPI• Controlable  state• Controlable  script  execuYon• ConYnuous  interacYon• No  need  for  sessions• No  execuYon  Ymeouts
  • 30. The  PHP  binary php
  • 31. The  PHP  binaryUsage:  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
  • 32. InteracLve  mode  (-­‐a) $  php  -­‐a Interactive  shell php  >  echo  5+8; 13 php  >  function  addTwo($n) php  >  { php  {  return  $n  +  2; php  {  } php  >  var_dump(addtwo(2)); int(4) php  >
  • 33. InteracLve  mode  (-­‐a) $  php  -­‐a Tab   Interactive  shell compleYon php  >  stri[TAB][TAB] strip_tags          stripcslashes     stripslashes      stristr                 stripos                 php  >  stri
  • 34. Run  code  (-­‐r) $  php  -­‐r  "echo  date(Y-­‐m-­‐d  H:i:s);" 2011-­‐03-­‐02  22:04:45 $
  • 35. Config  directory  (-­‐c) $  php  -­‐c  /custom/dir/php.ini  script.php
  • 36. Define  custom  INI  seRng  (-­‐d) $  php  -­‐d  max_execution_time=20  -­‐r  $foo  =   ini_get("max_execution_time");   var_dump($foo); string(2)  "20" $
  • 37. Get  INI  informaLon  (-­‐i) Filtering   items $  php  -­‐i  |  grep  “log_” define_syslog_variables  =>  Off  =>  Off log_errors  =>  On  =>  On log_errors_max_len  =>  1024  =>  1024 $
  • 38. Syntax/lint  check  (-­‐l) Only   checks  parse   errors $  php  -­‐l  myFile.php No  syntax  errors  detected  in  myFile.php $
  • 39. Module  list  (-­‐m) $  php  -­‐m [PHP  Modules] bcmath bz2 calendar Core ctype curl date dba $
  • 40. Syntax  highlighLng  (-­‐s)<?phpecho  "Hello  world";$  php  -­‐s  helloworld.php  >  helloworld.html$
  • 41. Syntax  highlighLng  (-­‐s)<code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color:#007700">echo&nbsp;</span><spanstyle="color:#DD0000">"Hello&nbsp;world"</span><spanstyle="color: #007700">;</span></span><?phpecho "Hello world";
  • 42. Version  info  (-­‐v) $  php  -­‐v PHP  5.3.3-­‐1ubuntu9.3  with  Suhosin-­‐Patch   (cli)  (built:  Jan  12  2011  16:07:38)   Copyright  (c)  1997-­‐2009  The  PHP  Group Zend  Engine  v2.3.0,  Copyright  (c)  1998-­‐2010   Zend  Technologies $
  • 43. FuncLon  reflecLon  (-­‐-­‐rf)$  php  -­‐-­‐rf  json_encodeFunction  [  <internal:json>  function  json_encode  ]  {    -­‐  Parameters  [2]  {        Parameter  #0  [  <required>  $value  ]        Parameter  #1  [  <optional>  $options  ]    }}$
  • 44. Class  reflecLon  (-­‐-­‐rc) $  php  -­‐-­‐rc  stdclass Class  [  <internal:Core>  class  stdClass  ]  {    -­‐  Constants  [0]  {    }    -­‐  Static  properties  [0]  {    }    -­‐  Static  methods  [0]  {    }    -­‐  Properties  [0]  {    }    -­‐  Methods  [0]  {    } } $
  • 45. Extension  reflecLon  (-­‐-­‐re)$  php  -­‐-­‐re  jsonExtension  [  <persistent>  extension  #20  json  version  1.2.1  ]  {...    -­‐  Functions  {        Function  [  <internal:json>  function  json_encode  ]  {            -­‐  Parameters  [2]  {                Parameter  #0  [  <required>  $value  ]                Parameter  #1  [  <optional>  $options  ]            }        }...}
  • 46. Extension  INI  informaLon  (-­‐-­‐ri) $  php  -­‐-­‐ri  pdo PDO PDO  support  =>  enabled PDO  drivers  =>  mysql,  sqlite,  sqlite2 $
  • 47. Back  on  track
  • 48. Back  to  I/O
  • 49. Input  &  output Web CLI• $_SERVER • $_SERVER• $_GET • $argc/$argv• $_POST • $_ENV• $_COOKIE • getopt()• $_SESSION • STDIN/STDOUT/ STDERR• $_ENV
  • 50. Change  your  mindset
  • 51. Change  your  mindset Don’t  use  sessions  &  cookies Just  use  local  variables
  • 52. Change  your  mindset If  you  don’t  need  HTTP,  use  CLI E.g.   cronjobs Avoid  overhead
  • 53. Change  your  mindset Current  directory  !=  webroot CLI   scripts  are  ➡Use  dirname(__FILE__) executable   everywhere➡Use  chdir()➡Use  getcwd()
  • 54. STDIN <?php $handle = fopen(php://stdin,r); while(!feof($handle)){     $line = trim(fgets($handle));     if(strlen($line) > 0){         echo strrev($line).PHP_EOL;     } } fclose($handle);
  • 55. STDIN <?php $handle = fopen(php://stdin,r); while(!feof($handle)){     $line = trim(fgets($handle));     if(strlen($line) > 0){         echo strrev($line).PHP_EOL;     } } fclose($handle);
  • 56. STDIN <?php while(!feof(STDIN)){     $line = trim(fgets(STDIN));     if(strlen($line) > 0){         echo strrev($line).PHP_EOL;     } }
  • 57. STDIN Stream   that  is  opened   <?php by  default while(!feof(STDIN)){     $line = trim(fgets(STDIN));     if(strlen($line) > 0){         echo strrev($line).PHP_EOL;     } }
  • 58. STDIN The   Stream   that  is  opened   proof  ! by  default $  php  -­‐r  "var_dump(STDIN);" resource(1)  of  type  (stream) $
  • 59. Wordcount  example<?php$wordArray = array();while(!feof(STDIN)){    $line = trim(fgets(STDIN));    if(strlen($line) > 0){        foreach(preg_split(/[s]+/,$line) as $word){            if(!array_key_exists($word,$wordArray)){                $wordArray[$word] = 0;            }            $wordArray[$word]++;        }    }}ksort($wordArray);foreach($wordArray as $word=>$count){    echo "$word: $count".PHP_EOL;}
  • 60. Wordcount  example$  cat  wordcount.txt  Barcelona  ThijsThijsBarcelonaThijs  PHPThijsBarcelona$  cat  wordcount.txt    |  php  wordcount.php  PHP:  1Thijs:  4Barcelona:  3$
  • 61. STDOUT STDOUT   ==   echo<?php$handle = fopen(php://stdout,w);fwrite($handle,Hello world);fclose($handle);
  • 62. STDOUT<?phpfwrite(STDOUT,Hello world);
  • 63. STDERR<?php$handle = fopen(php://stderr,w);fwrite($handle,Serious error!);fclose($handle);
  • 64. STDERR<?phpfwrite(STDERR,Serious error!);
  • 65. Mixing  STDOUT  &  STDERR<?phpfwrite(STDOUT,STDOUT output.PHP_EOL);fwrite(STDERR,STDERR output.PHP_EOL);$  php  stdmix.php  STDOUT  outputSTDERR  output$
  • 66. Mixing  STDOUT  &  STDERR<?php Looks  fwrite(STDOUT,STDOUT output.PHP_EOL); the  samefwrite(STDERR,STDERR output.PHP_EOL);$  php  stdmix.php  STDOUT  outputSTDERR  output$
  • 67. Mixing  STDOUT  &  STDERR$  php  stdmix.php  >  /dev/null  STDERR  output$$  php  stdmix.php  &>    /dev/null$
  • 68. Mixing  STDOUT  &  STDERR STDOUT   is  caught$  php  stdmix.php  >  /dev/null   STDOUT  STDERR  output$ &  STDERR  are   caught$  php  stdmix.php  &>    /dev/null$
  • 69. AlternaLve  output<?phpfclose(STDOUT);$handle = fopen(realpath(dirname(__FILE__)./output.txt),a);echo "Hello world!".PHP_EOL;fclose($handle);
  • 70. AlternaLve  output<?phpfclose(STDOUT);$handle = fopen(realpath(dirname(__FILE__)./output.txt),a);echo "Hello world!".PHP_EOL;fclose($handle); echo   output  is  wrioen   to  file
  • 71. Piping$  php  -­‐r  for($i=0;$i<10;$i++)  echo  $i.PHP_EOL;0123456789$  php  -­‐r  for($i=0;$i<10;$i++)  echo  $i.PHP_EOL;  |  wc  -­‐l            10$
  • 72. Readline<?php$name = readline("Whats your name: ");$location = readline("Where do you live: ");echo PHP_EOL."Hello $name from $locationn";$  php  readline.php  Whats  your  name:  ThijsWhere  do  you  live:  BelgiumHello  Thijs  from  Belgium$
  • 73. Shebang  !
  • 74. Shebang  !#!/usr/bin/php<?phpecho "Hello world".PHP_EOL;$  chmod  +x  shebang.php$  ./shebang.phpHello  world$
  • 75. Encore
  • 76. Process  Control  should  not  be  enabled   within  a  web  server  environment  and   unexpected  results  may  happen  if  any  Process  Control  funcYons  are  used  within   a  web  server  environment.
  • 77. Forking PID  value   determines   context Copy  <?php program  $pid = pcntl_fork();if ($pid == -1) { execuYon //Forking failed} else if ($pid) { //Parent logic} else { PID  of  child   //Child logic} process
  • 78. Forking<?php$pid = pcntl_fork();if ($pid == -1) {     die(could not fork);} else if ($pid) {     echo "[parent] Starting".PHP_EOL;     pcntl_wait($status);     echo "[parent] Exiting".PHP_EOL;} else {        echo "[child] Starting".PHP_EOL;    for($i=0;$i<3;$i++){        echo "[child] Loop $i".PHP_EOL;        sleep(1);    }    echo "[child] Exiting".PHP_EOL;    exit;}
  • 79. Forking Perform   forking<?php$pid = pcntl_fork();if ($pid == -1) {     die(could not fork); Wait  for  child  } else if ($pid) { terminaYon     echo "[parent] Starting".PHP_EOL;     pcntl_wait($status);     echo "[parent] Exiting".PHP_EOL;} else {        echo "[child] Starting".PHP_EOL;    for($i=0;$i<3;$i++){        echo "[child] Loop $i".PHP_EOL;        sleep(1);    }    echo "[child] Exiting".PHP_EOL;    exit;}
  • 80. Signals<?phpdeclare(ticks = 1);function sig_handler($signo){     switch ($signo) {         case SIGTERM:             echo PHP_EOL."SIGTERM".PHP_EOL;             exit();             break;         case SIGINT:             echo PHP_EOL."SIGINT".PHP_EOL;             exit();             break;     }}pcntl_signal(SIGTERM, "sig_handler");pcntl_signal(SIGINT, "sig_handler");sleep(100);
  • 81. Signals<?phpdeclare(ticks = 1); Process   terminaYonfunction sig_handler($signo){     switch ($signo) {         case SIGTERM: Process               echo PHP_EOL."SIGTERM".PHP_EOL;             exit();             break;         case SIGINT: interrupYon             echo PHP_EOL."SIGINT".PHP_EOL;             exit();             break; Catch  signals     }}pcntl_signal(SIGTERM, "sig_handler");pcntl_signal(SIGINT, "sig_handler");sleep(100);
  • 82. POSIX  process  control  funcLons<?phpecho "[prefork] PID:".posix_getpid().", parent PID: ".posix_getppid().PHP_EOL;$pid = pcntl_fork();if ($pid == -1) {  die(could not fork);} else if ($pid == 0) {echo "[child] PID: ".posix_getpid().", parent PID: ".posix_getppid().PHP_EOL;  exit;} else {  echo "[parent] PID: ".posix_getpid().", parent PID: ".posix_getppid().PHP_EOL;  pcntl_wait($status);
  • 83. Parent  PID   Prefork  PID  POSIX  process  c==   funcLons of  parent   ontrol   ==  <?phpsession  PID parent  PIDecho "[prefork] PID:".posix_getpid().", parent PID: ".posix_getppid().PHP_EOL;$pid = pcntl_fork();if ($pid == -1) { child  PID     die(could not fork); child  PID} else if ($pid == 0) {        echo "[child] PID: ".posix_getpid().", parent PID: ".posix_getppid().PHP_EOL; parent          exit;} else { PID        echo "[parent] PID: ".posix_getpid().", parent PID: ".posix_getppid().PHP_EOL;        pcntl_wait($status);}
  • 84. POSIX  process  control  funcLons<?php$pid=pcntl_fork();if ($pid == -1) {    die("could not fork");} else if ($pid) {    $exists = posix_kill($pid,0)?still:no longer;    echo "[parent] Child process $pid $exists exists".PHP_EOL;    echo "[parent] Killing child process $pid".PHP_EOL;    posix_kill($pid,SIGTERM);    echo "[parent] Child process $pid killed".PHP_EOL;    pcntl_wait($status);    $exists = posix_kill($pid,0)?still:no longer;    echo "[parent] Child process $pid $exists exists".PHP_EOL;} else {    while(true){        sleep(100);    }    exit;}
  • 85. POSIX  process  control  funcLons “KILL  0”  checks  <?php$pid=pcntl_fork(); existenceif ($pid == -1) {    die("could not fork");} else if ($pid) { Send  SIGTERM      $exists = posix_kill($pid,0)?still:no longer;    echo "[parent] Child process $pid $exists exists".PHP_EOL; signal    echo "[parent] Killing child process $pid".PHP_EOL;    posix_kill($pid,SIGTERM);    echo "[parent] Child process $pid killed".PHP_EOL;    pcntl_wait($status);    $exists = posix_kill($pid,0)?still:no longer;    echo "[parent] Child process $pid $exists exists".PHP_EOL;} else {    while(true){ Child  process          sleep(100);    } is  dead    exit;}
  • 86. Talk   dedicated  to   process  control  Check  this  guy  out  ! in  PHP Jeroen  Keppens:  @jkeppens http://www.slideshare.net/jkeppens/ zendcon-­‐2011-­‐php-­‐in-­‐the-­‐dark
  • 87. •January  27th  &  28th  2012•Best  Western  Hotel  Ter  Elst  Antwerp  (Belgium)•Call  For  Papers  CLOSED•Schedule  &  Ycket  announcements  in  a  couple  of  weeks
  • 88. Q&A
  • 89. Thanks  !