On Github stevegrunwell / building-for-php-cli
Steve Grunwell@stevegrunwell
#!/usr/bin/env php <?php // Do stuff
Two ways to invoke PHP on the CLI:
# 1. Pass the file to the php binary $ php my-command.php
# 2. Execute the file directly if using the php shebang. $ chmod +x my-command.php $ ./my-command.php
Good CLI commands should be composable!
Developers should write programs that can communicate easily with other programs. This rule aims to allow developers to break down projects into small, simple programs rather than overly complex monolithic programs.
Eric S. Raymond, The Art of Unix Programming
Scripts can use php_sapi_name() (or the PHP_SAPI constant) to determine the Server API being used.
// Make sure this script is being run over the PHP CLI! if ('cli' !== php_sapi_name()) { return; }
Developers should design programs so that they do not print unnecessary output. This rule aims to allow other programs and developers to pick out the information they need from a program's output without having to parse verbosity.
Eric S. Raymond, The Art of Unix Programming
joomlatools.com/developer/tools/console
# ArgExample.php printf('There were %d arguments passed to PHP:' . PHP_EOL, $argc); print_r($argv);
$ php ArgExample.php abc 123
There were 3 arguments passed to PHP: Array ( [0] => ArgExample.php [1] => abc [2] => 123 )
`ls -al` === shell_exec('ls -al')If you require multiple lines of output, use shell_exec()
Escapes any meta-characters that could be used to execute arbitrary commands
$name = 'steve && rm -rf /'; # Oh no, $name isn't being escaped! exec('greet-user ' . $name);
> Hello, steve # proceeded by your system being destroyed
$name = 'steve && rm -rf /'; # Nice try, user! exec('greet-user ' . escapeshellarg($name));
> Hello, steve && rm -rf / # What an odd name!
$name = getenv('DEMO_NAME'); if ($name) { printf('Hey, I recognize you, %s!' . PHP_EOL, $name); $name = sprintf('My old friend, %s!', $name); } else { echo "I don't know you, so I'll just call you Fred." . PHP_EOL; $name = 'Fred'; } // Update DEMO_NAME and call the system's echo program. putenv('DEMO_NAME=' . $name); passthru('echo $DEMO_NAME');
export DEMO_NAME="Steve"
> Hey, I recognize you, Steve! > My old friend, Steve!
Otherwise:
> I don't know you, so I'll just call you Fred. > Fred
if (! isset($argv['1'])) { echo "Missing required argument!"; exit(1); } // Do something awesome
$ php my-script.php foo && echo "Success" $ php my-script.php && echo "You will never see this"
A process that continually runs in the background
while ( $run ) { // do something! }
<?php use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class SymfonyExample extends Command { // ...
/** * Define what the command should be called and what arguments it * should accept. */ protected function configure() { $this ->setName('symfony-example') ->setDescription('Greet a user by name.') ->addArgument( 'name', InputArgument::REQUIRED, 'The name of the user' ); }
/** * Execute the command. * * @param InputInterface $input The input interface. * @param OutputInterface $output The output interface. */ protected function execute($input, $output) { $output->writeln(sprintf( '<comment>Symfony says "hello", %s!</comment>', $input->getArgument('name') )); }
$ php examples/SymfonyExample.php symfony-example Steve
> Symfony says "hello", Steve!
#!/usr/bin/env php <?php // Require dependencies. require_once __DIR__ . '/../vendor/autoload.php'; $limit = cli\prompt('How high should I count?', 10); $loud = cli\choose('Shall I shout it'); $suffix = 'y' === $loud ? '!' : '.'; for ($i = 1; $i <= $limit; $i++) { cli\line($i . $suffix); }
$ php examples/PHPCliToolsExample.php
$ php examples/PHPCliToolsExample.php How high should I count? [10]: 5 Shall I shout it? [y/N]y 1! 2! 3! 4! 5!
/** * Example WP-CLI script. */ class Example_WP_CLI_Command extends WP_CLI_Command { // At least one public method. } WP_CLI::add_command( 'example-command', 'Example_WP_CLI_Command' );
/** * Display the latest posts from a given user. * * ## OPTIONS * * <login> * : The user login to collect stats for. * * @subcommand latest-posts-by-user */ public function latest_posts_by_user( $args, $assoc_args ) { // Do something! }
public function latest_posts_by_user( $args, $assoc_args ) { $user = get_user_by( 'login', $args['0'] ); if ( ! $user ) { return WP_CLI::error( 'The specified user login does not exist!' ); } $posts = get_posts( array( 'author' => $user->ID ) ); $fields = array( 'ID', 'post_title', 'post_date' ); return WP_CLI\Utils\format_items( 'table', $posts, $fields ); }
$ wp example-command latest-posts-by-user admin
+-----+---------------+---------------------+ | ID | post_title | post_date | +-----+---------------+---------------------+ | 7 | A third post | 2016-04-08 14:32:00 | | 5 | Another post | 2016-04-05 18:32:23 | | 1 | Hello World! | 2015-11-12 01:14:38 | +-----+---------------+---------------------+
Steve Grunwellstevegrunwell.com10up.comnow hiring!