Your SlideShare is downloading. ×
Cli the other SAPI confoo11
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Cli the other SAPI confoo11

3,283
views

Published on

My command line PHP talks for Confoo 2011 in Montreal Canada.

My command line PHP talks for Confoo 2011 in Montreal Canada.

Published in: Technology

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,283
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
25
Comments
0
Likes
1
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 Confoo Thursday  March  10th  2011 Montreal,  Canada phpThijs  FerynEvangelist+32  (0)9  218  79  06thijs@combellgroup.com
  • 2. About  me I’m  an  Evangelist  at  Combell
  • 3. About  me I’m  a  board  member  at  PHPBenelux
  • 4. I  live  in  the  wonderful  city  of  Bruges MPBecker  -­‐  Bruges  by  Night  hWp://www.flickr.com/photos/galverson2/3715965933
  • 5. Follow  me  on  Twi+er:  @ThijsFerynGive  me  feedback:  h+p://joind.in/2852 Read  my  blog:  h+p://blog.feryn.eu
  • 6. SAPI  according  to  Wikipedia“The  Server  Applica^on  Programming  Interface  (SAPI)  is  the  generic  term  used  to  designate  direct  module  interfaces  to  web  server  applica^ons”
  • 7. SAPI  according  to  Wikipedia The  way  you  interact  with  PHP
  • 8. Common  SAPIs • Apache/Apache  2 • CGI • FastCGI • ISAPI • CLI • GTK
  • 9. The  CLI  SAPI  according  to  php.net As  of  version  4.3.0,  PHP  supports  a  new  SAPI   type  (Server  Applica^on  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)  applica^ons  with  PHP
  • 10. The  CLI  SAPI  according  to  php.netPHP  script  execu^on  via  the  command  line  interface
  • 11. When  to  use• In  crons• For  batch  tasks• For  worker  processes• Daemons• Process  control• Interac^on  with  other  binaries
  • 12. CLI 101
  • 13. CLI 101The PHP binaryPassing argumentsReading from STDINI/O with pipes
  • 14. CLI 101Invoking a script with the PHP binaryphp  file.php
  • 15. CLI 101 Passing argumentsphp  file.php  arg1  arg2
  • 16. CLI 101 interpreting arguments<?phpecho "Number of arguments {$argc}n";foreach($argv as $key=>$argument){    echo "Argument # {$key}: {$argument}n"; }
  • 17. CLI 101 interpreting arguments Argument   Argument   count array<?phpecho "Number of arguments {$argc}n";foreach($argv as $key=>$argument){    echo "Argument # {$key}: {$argument}n"; }
  • 18. 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$
  • 19. CLI 101 interpreting arguments$_SERVER[‘argc’] $argc$_SERVER[‘argv’] $argv !!! register_argc_argv !!!
  • 20. CLI 101 getopt<?php$arguments = getopt(ab:c::);var_dump($arguments);
  • 21. CLI 101 getopt Op^onal   Flag   (no  value) value<?php$arguments = getopt(ab:c::);var_dump($arguments); Required   value
  • 22. CLI 101php  getopt.php  -­‐a  -­‐b  2  -­‐c3array(3)  {    ["a"]=> No      bool(false)    ["b"]=> spacing  for      string(1)  "2" op^onal      ["c"]=> arguments    string(1)  "3"}
  • 23. CLI 101 getopt: longopts<?php$arguments = getopt(,array(arg1,arg2:,arg3::));var_dump($arguments);
  • 24. CLI 101php  getopt2.php  -­‐-­‐arg1  -­‐-­‐arg2  123  -­‐-­‐arg3=xarray(3)  {    ["arg1"]=>    bool(false) Mind      ["arg2"]=> the  “=”  sign    string(3)  "123"    ["arg3"]=>    string(1)  "x"}
  • 25. 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);
  • 26. CLI 101$  cat  test.txt  |  php  stdin.php  enOowTeerhT$
  • 27. CLI 101$  cat  test.txt  |  php  stdin.php  enOowT Output   Convert  eerhT$ file output  to   input  with   pipes
  • 28. Comparing  the  Apache  &  CLI  SAPI
  • 29. Comparing  the  Apache  &  CLI  SAPI Web  based  SAPI’s• HTTP  is  a  stateless  protocol• Request/response  based• Limited  interac^on• Sessions  &  cookies  as  workaround• Execu^on  ^meouts• Limited  request/response  size
  • 30. Comparing  the  Apache  &  CLI  SAPI CLI  SAPI• Controlable  state• Controlable  script  execu^on• Con^nuous  interac^on• No  need  for  sessions• No  execu^on  ^meouts
  • 31. Measuring  the  state
  • 32. Input  &  output
  • 33. Input  &  output Web CLI• $_SERVER • $_SERVER• $_GET • $argc/$argv• $_POST • $_ENV• $_COOKIE • getopt()• $_SESSION • STDIN/STDOUT/ STDERR• $_ENV
  • 34. Change  your  mindset
  • 35. Change  your  mindset Don’t  use  sessions  &  cookies Just  use  local  variables
  • 36. Change  your  mindset Don’t  “get”  your  input Just  “read”  it
  • 37. Change  your  mindset Don’t  bundle  your  output You  can  use  distributed  output
  • 38. Change  your  mindset If  you  don’t  need  HTTP,  use  CLI E.g.   cronjobs Avoid  overhead
  • 39. Change  your  mindset Current  directory  !=  webroot CLI   scripts  are  ➡Use  dirname(__FILE__) executable   everywhere➡Use  chdir()➡Use  getcwd()
  • 40. The  PHP  binary php
  • 41. 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
  • 42. InteracOve  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  >
  • 43. InteracOve  mode  (-­‐a) $  php  -­‐a Tab   Interactive  shell comple^on php  >  stri[TAB][TAB] strip_tags          stripcslashes     stripslashes      stristr                 stripos                 php  >  stri
  • 44. Run  code  (-­‐r) $  php  -­‐r  "echo  date(Y-­‐m-­‐d  H:i:s);" 2011-­‐03-­‐02  22:04:45 $
  • 45. Config  directory  (-­‐c) $  php  -­‐c  /custom/dir/php.ini  script.php
  • 46. Define  custom  INI  seSng  (-­‐d) $  php  -­‐d  max_execution_time=20  -­‐r  $foo  =   ini_get("max_execution_time");  var_dump ($foo); string(2)  "20" $
  • 47. Get  INI  informaOon  (-­‐i) Filtering   items $  php  -­‐i  |  grep  “log_” define_syslog_variables  =>  Off  =>  Off log_errors  =>  On  =>  On log_errors_max_len  =>  1024  =>  1024 $
  • 48. Syntax/lint  check  (-­‐l) Only   checks  parse   errors $  php  -­‐l  myFile.php No  syntax  errors  detected  in  myFile.php $
  • 49. Module  list  (-­‐m) $  php  -­‐m [PHP  Modules] bcmath bz2 calendar Core ctype curl date dba $
  • 50. Syntax  highlighOng  (-­‐s)<?phpecho  "Hello  world";$  php  -­‐s  helloworld.php  >  helloworld.html$
  • 51. Syntax  highlighOng  (-­‐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";
  • 52. 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 $
  • 53. FuncOon  reflecOon  (-­‐-­‐rf)$  php  -­‐-­‐rf  json_encodeFunction  [  <internal:json>  function  json_encode  ]  {    -­‐  Parameters  [2]  {        Parameter  #0  [  <required>  $value  ]        Parameter  #1  [  <optional>  $options  ]    }}$
  • 54. Class  reflecOon  (-­‐-­‐rf) $  php  -­‐-­‐rc  stdclass Class  [  <internal:Core>  class  stdClass  ]  {    -­‐  Constants  [0]  {    }    -­‐  Static  properties  [0]  {    }    -­‐  Static  methods  [0]  {    }    -­‐  Properties  [0]  {    }    -­‐  Methods  [0]  {    } } $
  • 55. Extension  reflecOon  (-­‐-­‐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  ]            }        }...}
  • 56. Extension  INI  informaOon  (-­‐-­‐ri) $  php  -­‐-­‐ri  pdo PDO PDO  support  =>  enabled PDO  drivers  =>  mysql,  sqlite,  sqlite2 $
  • 57. Back  on  track
  • 58. Back  to  I/O
  • 59. 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);
  • 60. 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);
  • 61. STDIN <?php while(!feof(STDIN)){     $line = trim(fgets(STDIN));     if(strlen($line) > 0){         echo strrev($line).PHP_EOL;     } }
  • 62. STDIN Stream   that  is  opened   <?php by  default while(!feof(STDIN)){     $line = trim(fgets(STDIN));     if(strlen($line) > 0){         echo strrev($line).PHP_EOL;     } }
  • 63. STDIN The   Stream   that  is  opened   proof  ! by  default $  php  -­‐r  "var_dump(STDIN);" resource(1)  of  type  (stream) $
  • 64. 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;}
  • 65. Wordcount  example$  cat  wordcount.txt  CanadaThijsCanadaThijsThijsConfoo$  cat  wordcount.txt    |  php  wordcount.php  Canada:  2Confoo:  1Thijs:  3$
  • 66. STDOUT STDOUT   ==   echo<?php$handle = fopen(php://stdout,w);fwrite($handle,Hello world);fclose($handle);
  • 67. STDOUT<?phpfwrite(STDOUT,Hello world);
  • 68. STDERR<?php$handle = fopen(php://stderr,w);fwrite($handle,Serious error!);fclose($handle);
  • 69. STDERR<?phpfwrite(STDERR,Serious error!);
  • 70. Mixing  STDOUT  &  STDERR<?phpfwrite(STDOUT,STDOUT output.PHP_EOL);fwrite(STDERR,STDERR output.PHP_EOL);$  php  stdmix.php  STDOUT  outputSTDERR  output$
  • 71. Mixing  STDOUT  &  STDERR<?php Looks  fwrite(STDOUT,STDOUT output.PHP_EOL); the  samefwrite(STDERR,STDERR output.PHP_EOL);$  php  stdmix.php  STDOUT  outputSTDERR  output$
  • 72. Mixing  STDOUT  &  STDERR$  php  stdmix.php  >  /dev/null  STDERR  output$$  php  stdmix.php  &>    /dev/null$
  • 73. Mixing  STDOUT  &  STDERR STDOUT   is  caught$  php  stdmix.php  >  /dev/null   STDOUT  STDERR  output$ &  STDERR  are   caught$  php  stdmix.php  &>    /dev/null$
  • 74. AlternaOve  output<?phpfclose(STDOUT);$handle = fopen(realpath(dirname(__FILE__)./output.txt),a);echo "Hello world!".PHP_EOL;fclose($handle);
  • 75. AlternaOve  output<?phpfclose(STDOUT);$handle = fopen(realpath(dirname(__FILE__)./output.txt),a);echo "Hello world!".PHP_EOL;fclose($handle); echo   output  is  wriWen   to  file
  • 76. 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$
  • 77. 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$
  • 78. Shebang  !#!/usr/bin/php<?phpecho "Hello world".PHP_EOL;$  chmod  +x  shebang.php$  ./shebang.phpHello  world$
  • 79. Encore
  • 80. PCNTL  according  to  php.net Process  Control  support  in  PHP   implements  the  Unix  style  of  process   crea^on,  program  execu^on,  signal   handling  and  process  termina^on.
  • 81. Process  Control  should  not  be  enabled   within  a  web  server  environment  and   unexpected  results  may  happen  if  any  Process  Control  func^ons  are  used  within   a  web  server  environment.
  • 82. Forking  according  to  Wikipedia In  compu^ng,  when  a  process  forks,  it   creates  a  copy  of  itself
  • 83. Forking PID  value   determines   context Copy  <?php program  $pid = pcntl_fork();if ($pid == -1) { execu^on //Forking failed} else if ($pid) { //Parent logic} else { PID  of  child   //Child logic} process
  • 84. 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;}
  • 85. Forking Perform   forking<?php$pid = pcntl_fork();if ($pid == -1) {     die(could not fork); Wait  for  child  } else if ($pid) { termina^on     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;}
  • 86. SignalsA  signal  is  a  limited  form  of  inter-­‐process   communica^on  used  in  Unix,  Unix-­‐like,   and  other  POSIX-­‐compliant  opera^ng  systems.  Essen^ally  it  is  an  asynchronous   no^fica^on  sent  to  a  process  in  order  to   no^fy  it  of  an  event  that  occurred.
  • 87. 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);
  • 88. Signals<?phpdeclare(ticks = 1); Process   termina^onfunction sig_handler($signo){     switch ($signo) {         case SIGTERM: Process               echo PHP_EOL."SIGTERM".PHP_EOL;             exit();             break;         case SIGINT: interrup^on             echo PHP_EOL."SIGINT".PHP_EOL;             exit();             break; Catch  signals     }}pcntl_signal(SIGTERM, "sig_handler");pcntl_signal(SIGINT, "sig_handler");sleep(100);
  • 89. POSIX  process  control  funcOons<?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);}
  • 90. Parent  PID   Prefork  PID  POSIX  process  c==   funcOons of  parent   ontrol   ==  <?php session  PID parent  PIDecho "[prefork] PID: ".posix_getpid().", parent PID: ".posix_getppid().PHP_EOL;$pid = pcntl_fork();if ($pid == -1) {     die(could not fork); child  PID} else if ($pid == 0) { child  PID        echo "[child] PID: ".posix_getpid().", parent PID: ".posix_getppid().PHP_EOL;        exit; parent  } else { PID        echo "[parent] PID: ".posix_getpid().", parent PID: ".posix_getppid().PHP_EOL;        pcntl_wait($status);}
  • 91. POSIX  process  control  funcOons<?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;}
  • 92. POSIX  process  control  funcOons “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;}
  • 93. Some  PCNTL  guidelines✓Detect  your  CWD✓Use  PID  files✓Control  you  file  privileges✓Detach  you  session✓Avoid  rogue  child  processes✓Cleanup  your  garbage
  • 94. Talk   dedicated  to   process  control  Check  this  guy  out  ! in  PHP Jeroen  Keppens:  @jkeppens http://www.slideshare.net/jkeppens/php-­‐in-­‐the-­‐dark
  • 95. Q&A
  • 96. Thanks  !

×