Slide 1

Slide 1 text

php CLI, the other SAPI By Thijs Feryn

Slide 2

Slide 2 text

Hi, I’m Thijs

Slide 3

Slide 3 text

I’m an at Evangelist

Slide 4

Slide 4 text

I’m a at board member

Slide 5

Slide 5 text

I’m @ThijsFeryn on Twitter

Slide 6

Slide 6 text

SAPI?

Slide 7

Slide 7 text

The way you interact with PHP

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

• mod_php • FastCGI • PHP-FPM • CLI • ISAPI • GTK

Slide 10

Slide 10 text

CLI SAPI? PHP script execution via the command line interface

Slide 11

Slide 11 text

When to use

Slide 12

Slide 12 text

• In crons • For batch tasks • For worker processes • Daemons • Process control • Interaction with other binaries

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

CLI 101

Slide 15

Slide 15 text

• The PHP binary • Passing arguments • Reading from STDIN • I/O with pipes

Slide 16

Slide 16 text

php  file.php Invoking a script with the PHP binary

Slide 17

Slide 17 text

php  file.php  arg1  arg2 Passing arguments

Slide 18

Slide 18 text

Interpreting arguments $argument){! echo "Argument # {$key}: {$argument} \n"; ! }

Slide 19

Slide 19 text

Interpreting arguments $argument){! echo "Argument # {$key}: {$argument} \n"; ! } Argument   count Argument   array

Slide 20

Slide 20 text

Interpreting arguments $  php  args.php  arg1  arg2   Number  of  arguments  3   Argument  #  0:  args.php   Argument  #  1:  arg1   Argument  #  2:  arg2   $   The   PHP  file  is  an   argument  too

Slide 21

Slide 21 text

$_SERVER[’argc’] $_SERVER[’argv’] $argc $argv Interpreting arguments register_argc_argv

Slide 22

Slide 22 text

GETOPT

Slide 23

Slide 23 text

Slide 24

Slide 24 text

GETOPT

Slide 25

Slide 25 text

GETOPT php  getopt.php  -­‐a  -­‐b  2  -­‐c3   array(3)  {      ["a"]=>      bool(false)      ["b"]=>      string(1)  "2"      ["c"]=>      string(1)  "3"   }   No   spacing  for   op8onal   arguments

Slide 26

Slide 26 text

GETOPT Long options

Slide 27

Slide 27 text

GETOPT Long options php  getopt2.php  -­‐-­‐arg1  -­‐-­‐arg2  123  -­‐-­‐arg3=x   array(3)  {      ["arg1"]=>      bool(false)      ["arg2"]=>      string(3)  "123"      ["arg3"]=>      string(1)  "x"   }   Mind   the  “=”  

Slide 28

Slide 28 text

Reading from STDIN

Slide 29

Slide 29 text

Reading from STDIN 0){! echo strrev($line).PHP_EOL;! }! }! fclose($handle);

Slide 30

Slide 30 text

Reading from STDIN $  cat  test.txt  |  php  stdin.php     enO   owT   eerhT   $

Slide 31

Slide 31 text

Reading from STDIN $  cat  test.txt  |  php  stdin.php     enO   owT   eerhT   $ Output   file Convert   output  to   input  with   pipes

Slide 32

Slide 32 text

Web vs CLI Web! CLI HTTP is a stateless protocol Controlable state Request/response based Controllable script execution Limited interaction Continuous interaction Execution timeouts No sessions required GET/POST/COOKIE/SESSION Arguments, STDIN, STDOUT, STDERR, exit codes

Slide 33

Slide 33 text

The PHP binary

Slide 34

Slide 34 text

Usage:  php  [options]  [-­‐f]    [-­‐-­‐]  [args...]                php  [options]  -­‐r    [-­‐-­‐]  [args...]                php  [options]  [-­‐B  ]  -­‐R     [-­‐E  ]  [-­‐-­‐]  [args...]                php  [options]  [-­‐B  ]  -­‐F     [-­‐E  ]  [-­‐-­‐]  [args...]                php  [options]  -­‐-­‐  [args...]                php  [options]  -­‐a The PHP binary

Slide 35

Slide 35 text

Interactive mode $  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  >  

Slide 36

Slide 36 text

Interactive mode $  php  -­‐a   Interactive  shell   ! php  >  stri[TAB][TAB]   strip_tags          stripcslashes     stripslashes      stristr                 stripos                   php  >  stri   ! Tab   comple8on

Slide 37

Slide 37 text

Run code $  php  -­‐r  "echo  date('Y-­‐m-­‐d  H:i:s');"   2011-­‐03-­‐02  22:04:45   $

Slide 38

Slide 38 text

Config directory $  php  -­‐c  /custom/dir/php.ini  script.php

Slide 39

Slide 39 text

Custom ini settings $  php  -­‐d  max_execution_time=20  -­‐r  '$foo  =   ini_get("max_execution_time");   var_dump($foo);'   string(2)  "20"   $

Slide 40

Slide 40 text

Get ini settings $  php  -­‐i  |  grep  “log_”   define_syslog_variables  =>  Off  =>  Off   log_errors  =>  On  =>  On   log_errors_max_len  =>  1024  =>  1024   $ Filtering   items

Slide 41

Slide 41 text

Lint checking $  php  -­‐l  myFile.php   No  syntax  errors  detected  in  myFile.php   $ Only   checks  parse   errors

Slide 42

Slide 42 text

List modules $  php  -­‐m   [PHP  Modules]   bcmath   bz2   calendar   Core   ctype   curl   date   dba   $

Slide 43

Slide 43 text

Syntax highlighting $  php  -­‐s  helloworld.php  >  helloworld.html   $

Slide 44

Slide 44 text

Syntax highlighting ! <?php
echo "Hello world";!
!

Slide 45

Slide 45 text

Version $  php  -­‐v   PHP  5.4.17  (cli)  (built:  Aug  25  2013   02:03:38)   Copyright  (c)  1997-­‐2013  The  PHP  Group   Zend  Engine  v2.4.0,  Copyright  (c)  1998-­‐2013   Zend  Technologies   $

Slide 46

Slide 46 text

Function reflection $  php  -­‐-­‐rf  json_encode   Function  [    function   json_encode  ]  {   !    -­‐  Parameters  [2]  {          Parameter  #0  [    $value  ]          Parameter  #1  [    $options  ]      }   }   $

Slide 47

Slide 47 text

Class reflection $  php  -­‐-­‐rc  stdclass   Class  [    class  stdClass  ]  {      -­‐  Constants  [0]  {      }      -­‐  Static  properties  [0]  {      }      -­‐  Static  methods  [0]  {      }      -­‐  Properties  [0]  {      }      -­‐  Methods  [0]  {      }   }   $

Slide 48

Slide 48 text

Extension reflection $  php  -­‐-­‐re  json   Extension  [    extension  #20  json  version   1.2.1  ]  {   ...      -­‐  Functions  {          Function  [    function  json_encode  ]  {   !            -­‐  Parameters  [2]  {                  Parameter  #0  [    $value  ]                  Parameter  #1  [    $options  ]              }          }   ...   }  

Slide 49

Slide 49 text

Extension information $  php  -­‐-­‐ri  pdo   ! PDO   ! PDO  support  =>  enabled   PDO  drivers  =>  mysql,  sqlite,  sqlite2   $

Slide 50

Slide 50 text

Built-in webserver $  php  -­‐S  0:8080  -­‐t  /var/www  /var/www/index.php   $   PHP  5.4.17  Development  Server  started  at  Mon   Jan  13  15:35:03  2014   Listening  on  http://0:8080   Document  root  is  /var/www   Press  Ctrl-­‐C  to  quit.

Slide 51

Slide 51 text

Built-in webserver $  php  -­‐S  0:8080  -­‐t  /var/www  /var/www/index.php   $   PHP  5.4.17  Development  Server  started  at  Mon   Jan  13  15:35:03  2014   Listening  on  http://0:8080   Document  root  is  /var/www   Press  Ctrl-­‐C  to  quit. Docroot Router IP   &  port

Slide 52

Slide 52 text

Slide 53

Slide 53 text

I/O

Slide 54

Slide 54 text

Change your mindset

Slide 55

Slide 55 text

Don’t use sessions & cookies. ! Just use local variables

Slide 56

Slide 56 text

Don’t use HTTP calls in crons

Slide 57

Slide 57 text

Current directory !== webroot • Use dirname(__FILE__) • Use chdir() • Use getcwd() CLI   scripts  are   executable   everywhere

Slide 58

Slide 58 text

STDIN 0){! echo strrev($line).PHP_EOL;! }! }! fclose($handle);

Slide 59

Slide 59 text

STDIN 0){! echo strrev($line).PHP_EOL;! }! }! fclose($handle);

Slide 60

Slide 60 text

STDIN 0){! echo strrev($line).PHP_EOL;! }! }!

Slide 61

Slide 61 text

STDIN 0){! echo strrev($line).PHP_EOL;! }! }! Stream   that  is  opened   by  default

Slide 62

Slide 62 text

The proof $  php  -­‐r  "var_dump(STDIN);"   resource(1)  of  type  (stream)   $

Slide 63

Slide 63 text

STDOUT

Slide 64

Slide 64 text

STDOUT

Slide 65

Slide 65 text

STDERR

Slide 66

Slide 66 text

STDERR

Slide 67

Slide 67 text

Mixing STDOUT & STDERR

Slide 68

Slide 68 text

Mixing STDOUT & STDERR $  php  stdmix.php  >  /dev/null     STDERR  output   $ $  php  stdmix.php  &>    /dev/null   $

Slide 69

Slide 69 text

Alternative output

Slide 70

Slide 70 text

Piping $  php  -­‐r  'for($i=0;$i<10;$i++)  echo  $i.PHP_EOL;'   0   1   2   3   4   5   6   7   8   9   $  php  -­‐r  'for($i=0;$i<10;$i++)  echo  $i.PHP_EOL;'  |  wc  -­‐l              10   $

Slide 71

Slide 71 text

Readline

Slide 72

Slide 72 text

Symfony\Component\Console

Slide 73

Slide 73 text

Symfony console component addCommands(array(! new Thijs\Console\Command\TestCommand()! ));! $app->run();

Slide 74

Slide 74 text

namespace Thijs\Console\Command;! ! use Symfony\Component\Console\Command\Command;! use Symfony\Component\Console\Input\InputInterface;! use Symfony\Component\Console\Output\OutputInterface;! use Symfony\Component\Console\Input\InputArgument;! use Symfony\Component\Console\Input\InputOption;! use Symfony\Component\Console\Formatter\OutputFormatterStyle;! ! class TestCommand extends Command {! } The command class

Slide 75

Slide 75 text

protected function configure() {! $this->setName("hello")! ->setDescription("Saying hello to the world")! ->addArgument('name',InputArgument::REQUIRED,'Your name')! ->addOption(! 'yell',! null,! InputOption::VALUE_NONE,! 'If set, the task will yell in uppercase letters'! )! ->setHelp('The '.$this- >getName().' command says hello to the world');! } Configure the command

Slide 76

Slide 76 text

protected function execute(InputInterface $input, OutputInterface $output) {! $text = 'Hello '.$input->getArgument('name');! if($input->getOption('yell')){! $text = strtoupper($text);! }! $output->writeln($text);! } Execute the command

Slide 77

Slide 77 text

$dialog = $this->getHelperSet()->get('dialog');! while($dialog->askConfirmation(! $output,! ’Continue with this action? [y/n]: ’,! false)){! $text = 'Hello ‚.$dialog->ask($output,! ! ! ! ! ! ! 'Who do you want to say hello to ?: ', 'world');! if($input->getOption('yell')){! $text = strtoupper($text);! }! $this->_hello[] = array($text);! } Adding dialogs

Slide 78

Slide 78 text

$output->writeln('Processing input');! $output->writeln('Please wait'); Adding color

Slide 79

Slide 79 text

$progress = $this->getHelperSet()->get('progress');! $progress->start($output, 50);! $i = 0;! while ($i++ < 50) {! ! $progress->advance();! usleep(50000);! }! $progress->finish(); Adding progress

Slide 80

Slide 80 text

$table = $this->getHelperSet()->get('table');! $table! ->setHeaders(array('Hello'))! ->setRows($this->_hello);! $table->render($output); Adding table output

Slide 81

Slide 81 text

Adding table output bin/console.php  hello  Thijs   Continue  with  this  action?  [y/n]:  y   Who  do  you  want  to  say  hello  to  ?:  PHP   Continue  with  this  action?  [y/n]:  y   Who  do  you  want  to  say  hello  to  ?:  ElePHPants   Continue  with  this  action?  [y/n]:  n   Processing  input   Please  wait    50/50  [============================]  100%   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+   |  Hello                        |   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+   |  Hello  Thijs            |   |  Hello  PHP                |   |  Hello  ElePHPants  |   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+

Slide 82

Slide 82 text

Shebang

Slide 83

Slide 83 text

#!/usr/bin/php!

Slide 84

Slide 84 text

Encore?

Slide 85

Slide 85 text

PCNTL

Slide 86

Slide 86 text

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.

Slide 87

Slide 87 text

Forking

Slide 88

Slide 88 text

Forking

Slide 89

Slide 89 text

Forking

Slide 90

Slide 90 text

Forking

Slide 91

Slide 91 text

Signals

Slide 92

Slide 92 text

Signals

Slide 93

Slide 93 text

POSIX process control functions

Slide 94

Slide 94 text

POSIX

Slide 95

Slide 95 text

POSIX

Slide 96

Slide 96 text

No content