SlideShare a Scribd company logo
SYMFONY CONSOLE: BUILD
AWESOME COMMAND LINE
SCRIPTS WITH EASE
Oscar Merida
August 1, 2017
GROUND RULES
IN THIS TALK
You’ll learn:
How to create your own CLI scrips like Composer and Drupal Console.
How to add commands
How to get input from users, display feedback
How to package it as a standalone le.
In this talk, I’ll show you how you can create a command line application like composer or drupal console to make your life easier.
WHY? TO AUTOMATE TASKS.
Prevent errors on routine tasks and speed them up too!
If you do something frequently or if a task has a lot of steps, computers are the perfect tool to perform them repetitively.
IS IT WORTH THE TIME?
From https://xkcd.com/1205/
Before you automate all the things, check if its worth sinking a lot of time into it. It makes sense to spend time automating the things you do very
frequently and take long to do. If a task is particularly error prone, automate it too. As usual, there’s an XKCD comic to reference.
EXAMPLES
Generate a new set of tickets in an issue tracker.
Prepare a mailchimp template for a campaign.
Generate images to share on social media.
Combine CSV les into Excel Spreadsheet.
What kind of tasks can you automate? With the right packages, almost anything. These are some examples of tasks I’ve automated to save myself
time.
MAKING A CLI APP
DIRECTORY SETUP
├── app
│ ├── resources
│ ├── src
│ └── vendor
└── build
This is a structure I typically use. All code goes in app, later we’ll use the build directory to creat a phar archive. resources holds templates,
images, other files commands might need. src is where your application’s commands will live.
INSTALLING SYMFONY CONSOLE
cd app
composer require symfony/console
Symfony’s console component is easily installed via composer. Issue this command, and it along with its dependencies will be downloaded to your
app/vendor folder.
AUTOLOADER
Create a namespace and directory for your application under src
"autoload": {
"psr-4": {
"GovCon": "src/GovCon",
}
}
Leverage composer’s PSR-4 autoloader to find your commands and code. We map our GovCon namespace to files in the src/GovCon directory.
Remember to run composer dump-autoload after adding this section to composer.json.
YOUR APP
Create app/govcon.php.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use SymfonyComponentConsoleApplication;
// now run it
$application = new Application();
$application->run();
This is the file to execute to run a command. We include our autolaoder, then create an Application object and run() it. Of course, it doesn’t do
much at this point.
ADDING A COMMAND
Let’s add on to display the current time.
<?php
namespace GovCon;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;
class WhatTime extends Command {
}
We extend the base Command class. We must implement the configure() and execute() methods.
CONFIGURING COMMANDS
protected function configure() {
$this->setName('gc:whatTime')
->setDescription('Display the current time.')
->setHelp('Print the current time to STDOUT') //opt
;
}
This command sets the name to use to execute a command. The description is shown when a list of all commands is shown.
EXECUTE() METHOD
public function execute(InputInterface $input, OutputInterface $output)
{
$now = new DateTime();
$output->writeln('It is now ' . $now->format('g:i a'));
}
This is where we do any of the work needed.
NOW RUN IT:
app$ php govcon.php gc:whatTime
It is now 2:56 pm
GET USER INPUT
Questions let us get interactive input from the user.
use SymfonyComponentConsoleQuestionQuestion;
public function execute(InputInterface $input, OutputInterface $output)
{
$helper = $this->getHelper('question');
$default = 'Human';
$outputQ = new Question('What is your name? [' . $default. ']: ', $default);
$name = $helper->ask($input, $output, $outputQ);
$now = new DateTime();
$output->writeln('It is now ' . $now->format('g:i a') . ', ' . $name);
}
RESULT
app$ php govcon.php gc:whatTime
Waht is your name? [Human]: Oscar
It is now 3:02 pm, Oscar
A NOTE ON OUTPUT
We saw how to use $output->writeln() to send output. There’s also
$output->write()
You can also colorize your output:
$output->writeln('<info>Starting processing</info>'; // green
$output->writeln('<comment>Starting processing</comment>'; // yellow
$output->writeln('<question>Starting processing</question>'; // black on cyan
$output->writeln('<error>Starting processing</>'; // white on red
POSITIONAL ARGUMENTS
We can con gure command line arguments to get input too. They can be
requred or options
php govcon.php gc:whatTime "F, j Y h:i:s"
What is your name? [Human]:
It is now July, 31 2017 03:13:26, Human
ARGUMENTS, CONFIGURE()
use SymfonyComponentConsoleInputInputArgument;
protected function configure() {
$this->setName('gc:whatTime')
->setDescription('Display the current time.')
->addArgument('date_format', InputArgument::REQUIRED, 'Date format')
;
}
ARGUMENTS, EXECUTE()
$format = $input->getArgument('date_format');
$now = new DateTime();
$output->writeln('It is now ' . $now->format($format) . ', ' . $name);
SWITCHES AKA COMMAND OPTIONS
Another way to get user input.
app$ php govcon.php gc:whatTime --format "H:i:s"
What is your name? [Human]:
It is now 15:19:31, Human
OPTIONS, CONFIGURE
use SymfonyComponentConsoleInputInputOption; // earlier
// ...
$this->setName('gc:whatTime')
->setDescription('Display the current time.')
->setHelp('Print the current time to STDOUT')
->addOption('format',
'f', // shorcut
InputOption::VALUE_OPTIONAL,
'Date format'
)
;
OPTIONS, EXECUTE
$format = $input->getOption('format') ?? 'g:i a';
$now = new DateTime();
$output->writeln(
'It is now ' . $now->format($format) . ', ' . $name
);
CHOICES AND QUESTIONS
Finally, you can let users choose from one or more options.
app$ php govcon.php gc:whatTime --format "H:i:s"
Which format do you prefer?
[military] H:i
[common ] g:i a
> military
It is now 15:27
CHOICE, EXECUTE
$choices = [
'military' => 'H:i',
'common' => 'g:i a',
];
$question = new ChoiceQuestion(
'<question>Which format do you prefer?</question> ', $choices
);
$helper = $this->getHelper('question');
$format = $helper->ask($input, $output, $question);
$now = new DateTime();
$output->writeln('It is now ' . $now->format($choices[$format]));
CONFIGURATION FILES
Use a con guration le to store credentials, or persist values between
runs.
->addOption('config',
null
InputOption::VALUE_REQUIRED,
'Configuration Files'
);
$file = $input->getOption('config') ?? '~/govcon.config.php';
$values = $this->readConfig($file); // parse it
The format for your config file can be whatever you can parse that is easily writeable by your users. It can be a simple ini file, YAML, json, xml, etc.
CREATING A .PHAR
A WHAT?
A Phar archive is used to distribute a complete PHP
application or library in a single le.
For the command line, a phar file gives us away to distribute ALL our files inside a single file. The PHP interpreter knows how to work with it. You’re
probably already familiar with at least one phar - composer.phar
BUILD SKELETON
There are multiple ways to build one, I’ll show you how I do it. See also
packaging Your Apps with Phar
BUILD-PHAR.PHP
<?php
define ('BASE_SRC', realpath(__DIR__ . '/../app') . '/');
$name = 'govcon.phar';
$app = 'govcon.php';
if (file_exists($name)) {
unlink($name);
}
$phar = new Phar($name, 0, $name);
$phar->setSignatureAlgorithm(Phar::SHA1);
// add everything under our APP dir
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(BASE_SRC, FilesystemIterator::SKIP_DOTS)
);
$phar->buildFromIterator($it, BASE_SRC);
Explain what this does
HAVE YOURSELF A PHAR
Once the build comopletes, you’ll have a govcon.phar le.
build$ ./govcon.phar gc:whatTime
Which format do you prefer?
[military] H:i
[common ] g:i a
> military
It is now 15:40
You can share this file with others. Place it somewhere in there $PATH and it’ll be available globally.
WORKING WITH FILES
In your app le get the path to resources/ and inject it to any comand
which needs it.
$resource_dir = __DIR__ . '/resources';
$application->add(new FooSomeCommand($resource_dir));
Use DirectoryIterator not glob() to get list of les
// copy over resources for this column
// phar doesn't support glob
$files = new DirectoryIterator($this->resource_dir . "/myfiles/");
foreach ($files as $file) {
}
If you’re copying files from inside your archive to the user’s file system, use the DirectoryIterorator.
THIRD PARTY LIBRARIES
Not all libraries may work with bundled les in a phar.
In my case, I couldn’t bundle some font files for the Intervention library to use for image manipulation.
SECURITY
If you need to use api_keys or credentials, don’t put them in your phar le.
Use a con guration le and make sure its locked down so only the current
user can read it.
CONCLUSION
Automation can save you time and prevent errors. Symfony Console
handles a lot of the plumbing so you can focus on your use case.
THANK YOU
@omerida
I publish php[architect], a monthly magazine for PHP developers. Check it
out: www.phparch.com
php[world] is our fall conference in Tyson’s Corner. world.phparch.com

More Related Content

PDF
Symfony 2.0 on PHP 5.3
PDF
The Enterprise Wor/d/thy/Press
PDF
WordPress REST API hacking
PDF
Keeping it Small: Getting to know the Slim Micro Framework
PDF
Advanced symfony Techniques
PPT
Introduction to php
PDF
The Enterprise Wor/d/thy/Press
PDF
WordPress REST API hacking
Symfony 2.0 on PHP 5.3
The Enterprise Wor/d/thy/Press
WordPress REST API hacking
Keeping it Small: Getting to know the Slim Micro Framework
Advanced symfony Techniques
Introduction to php
The Enterprise Wor/d/thy/Press
WordPress REST API hacking

What's hot (20)

ODP
Modern Web Development with Perl
PDF
Putting the Cat in the Catalogue: A Feline-Inspired OPAC Theme For Koha
PPTX
New in php 7
PDF
How to develop modern web application framework
PDF
関西PHP勉強会 php5.4つまみぐい
PPTX
Event Sourcing with php
PDF
Data Validation models
PPT
php 2 Function creating, calling, PHP built-in function
PPT
Awash in a sea of connections
PDF
優しいWAFの作り方
PPT
Introduction to web and php mysql
PPTX
Introduction To Power Shell
PPTX
Real time voice call integration - Confoo 2012
PPTX
Php server variables
PDF
Using HttpKernelInterface for Painless Integration
KEY
ISUCONアプリを Pythonで書いてみた
PPTX
PowerShell 101
PPT
Php my sql - functions - arrays - tutorial - programmerblog.net
PDF
Let's play a game with blackfire player
KEY
Actions filters
Modern Web Development with Perl
Putting the Cat in the Catalogue: A Feline-Inspired OPAC Theme For Koha
New in php 7
How to develop modern web application framework
関西PHP勉強会 php5.4つまみぐい
Event Sourcing with php
Data Validation models
php 2 Function creating, calling, PHP built-in function
Awash in a sea of connections
優しいWAFの作り方
Introduction to web and php mysql
Introduction To Power Shell
Real time voice call integration - Confoo 2012
Php server variables
Using HttpKernelInterface for Painless Integration
ISUCONアプリを Pythonで書いてみた
PowerShell 101
Php my sql - functions - arrays - tutorial - programmerblog.net
Let's play a game with blackfire player
Actions filters
Ad

Similar to Symfony console: build awesome command line scripts with ease (20)

PDF
What's New In Laravel 5
ODP
Zend Framework 1.9 Setup & Using Zend_Tool
PDF
Doctrine For Beginners
PDF
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
ODP
CodeIgniter PHP MVC Framework
PDF
Creating a modern web application using Symfony API Platform Atlanta
PDF
TYPO3 Scheduler
PDF
Lean Php Presentation
PDF
2023 - Drupalcon - How Drupal builds your pages
PDF
Drupalcon 2023 - How Drupal builds your pages.pdf
PPTX
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
PPTX
object oriented programming in PHP & Functions
PPT
PHP and COM
KEY
Phpne august-2012-symfony-components-friends
PDF
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
PDF
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
PDF
Building Testable PHP Applications
PDF
ReactPHP
PPTX
PSGI and Plack from first principles
ODP
Symfony CMF - PHP Conference Brazil 2011
What's New In Laravel 5
Zend Framework 1.9 Setup & Using Zend_Tool
Doctrine For Beginners
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
CodeIgniter PHP MVC Framework
Creating a modern web application using Symfony API Platform Atlanta
TYPO3 Scheduler
Lean Php Presentation
2023 - Drupalcon - How Drupal builds your pages
Drupalcon 2023 - How Drupal builds your pages.pdf
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
object oriented programming in PHP & Functions
PHP and COM
Phpne august-2012-symfony-components-friends
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Building Testable PHP Applications
ReactPHP
PSGI and Plack from first principles
Symfony CMF - PHP Conference Brazil 2011
Ad

More from Oscar Merida (11)

PDF
PHP OOP
PDF
Start using PHP 7
PDF
Integration Testing with Behat drupal
PDF
Staying Sane with Drupal NEPHP
PDF
Building with Virtual Development Environments
PDF
Staying Sane with Drupal (A Develper's Survival Guide)
PDF
How to Evaluate your Technical Partner
PDF
Building with Virtual Development Environments
PDF
Publishing alchemy with markdown and pandoc
PDF
Migrate without migranes
PDF
Hitch yourwagon
PHP OOP
Start using PHP 7
Integration Testing with Behat drupal
Staying Sane with Drupal NEPHP
Building with Virtual Development Environments
Staying Sane with Drupal (A Develper's Survival Guide)
How to Evaluate your Technical Partner
Building with Virtual Development Environments
Publishing alchemy with markdown and pandoc
Migrate without migranes
Hitch yourwagon

Recently uploaded (20)

PDF
Design an Analysis of Algorithms I-SECS-1021-03
PPTX
Transform Your Business with a Software ERP System
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
top salesforce developer skills in 2025.pdf
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
ISO 45001 Occupational Health and Safety Management System
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
System and Network Administraation Chapter 3
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
ai tools demonstartion for schools and inter college
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
Design an Analysis of Algorithms I-SECS-1021-03
Transform Your Business with a Software ERP System
VVF-Customer-Presentation2025-Ver1.9.pptx
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
top salesforce developer skills in 2025.pdf
Wondershare Filmora 15 Crack With Activation Key [2025
Understanding Forklifts - TECH EHS Solution
Odoo POS Development Services by CandidRoot Solutions
ISO 45001 Occupational Health and Safety Management System
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Internet Downloader Manager (IDM) Crack 6.42 Build 41
System and Network Administraation Chapter 3
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
ai tools demonstartion for schools and inter college
Design an Analysis of Algorithms II-SECS-1021-03
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Softaken Excel to vCard Converter Software.pdf
ManageIQ - Sprint 268 Review - Slide Deck
Which alternative to Crystal Reports is best for small or large businesses.pdf

Symfony console: build awesome command line scripts with ease

  • 1. SYMFONY CONSOLE: BUILD AWESOME COMMAND LINE SCRIPTS WITH EASE Oscar Merida August 1, 2017
  • 3. IN THIS TALK You’ll learn: How to create your own CLI scrips like Composer and Drupal Console. How to add commands How to get input from users, display feedback How to package it as a standalone le. In this talk, I’ll show you how you can create a command line application like composer or drupal console to make your life easier.
  • 4. WHY? TO AUTOMATE TASKS. Prevent errors on routine tasks and speed them up too! If you do something frequently or if a task has a lot of steps, computers are the perfect tool to perform them repetitively.
  • 5. IS IT WORTH THE TIME? From https://xkcd.com/1205/ Before you automate all the things, check if its worth sinking a lot of time into it. It makes sense to spend time automating the things you do very frequently and take long to do. If a task is particularly error prone, automate it too. As usual, there’s an XKCD comic to reference.
  • 6. EXAMPLES Generate a new set of tickets in an issue tracker. Prepare a mailchimp template for a campaign. Generate images to share on social media. Combine CSV les into Excel Spreadsheet. What kind of tasks can you automate? With the right packages, almost anything. These are some examples of tasks I’ve automated to save myself time.
  • 8. DIRECTORY SETUP ├── app │ ├── resources │ ├── src │ └── vendor └── build This is a structure I typically use. All code goes in app, later we’ll use the build directory to creat a phar archive. resources holds templates, images, other files commands might need. src is where your application’s commands will live.
  • 9. INSTALLING SYMFONY CONSOLE cd app composer require symfony/console Symfony’s console component is easily installed via composer. Issue this command, and it along with its dependencies will be downloaded to your app/vendor folder.
  • 10. AUTOLOADER Create a namespace and directory for your application under src "autoload": { "psr-4": { "GovCon": "src/GovCon", } } Leverage composer’s PSR-4 autoloader to find your commands and code. We map our GovCon namespace to files in the src/GovCon directory. Remember to run composer dump-autoload after adding this section to composer.json.
  • 11. YOUR APP Create app/govcon.php. <?php require_once __DIR__ . '/vendor/autoload.php'; use SymfonyComponentConsoleApplication; // now run it $application = new Application(); $application->run(); This is the file to execute to run a command. We include our autolaoder, then create an Application object and run() it. Of course, it doesn’t do much at this point.
  • 12. ADDING A COMMAND Let’s add on to display the current time. <?php namespace GovCon; use SymfonyComponentConsoleCommandCommand; use SymfonyComponentConsoleInputInputInterface; use SymfonyComponentConsoleOutputOutputInterface; class WhatTime extends Command { } We extend the base Command class. We must implement the configure() and execute() methods.
  • 13. CONFIGURING COMMANDS protected function configure() { $this->setName('gc:whatTime') ->setDescription('Display the current time.') ->setHelp('Print the current time to STDOUT') //opt ; } This command sets the name to use to execute a command. The description is shown when a list of all commands is shown.
  • 14. EXECUTE() METHOD public function execute(InputInterface $input, OutputInterface $output) { $now = new DateTime(); $output->writeln('It is now ' . $now->format('g:i a')); } This is where we do any of the work needed.
  • 15. NOW RUN IT: app$ php govcon.php gc:whatTime It is now 2:56 pm
  • 16. GET USER INPUT Questions let us get interactive input from the user. use SymfonyComponentConsoleQuestionQuestion; public function execute(InputInterface $input, OutputInterface $output) { $helper = $this->getHelper('question'); $default = 'Human'; $outputQ = new Question('What is your name? [' . $default. ']: ', $default); $name = $helper->ask($input, $output, $outputQ); $now = new DateTime(); $output->writeln('It is now ' . $now->format('g:i a') . ', ' . $name); }
  • 17. RESULT app$ php govcon.php gc:whatTime Waht is your name? [Human]: Oscar It is now 3:02 pm, Oscar
  • 18. A NOTE ON OUTPUT We saw how to use $output->writeln() to send output. There’s also $output->write() You can also colorize your output: $output->writeln('<info>Starting processing</info>'; // green $output->writeln('<comment>Starting processing</comment>'; // yellow $output->writeln('<question>Starting processing</question>'; // black on cyan $output->writeln('<error>Starting processing</>'; // white on red
  • 19. POSITIONAL ARGUMENTS We can con gure command line arguments to get input too. They can be requred or options php govcon.php gc:whatTime "F, j Y h:i:s" What is your name? [Human]: It is now July, 31 2017 03:13:26, Human
  • 20. ARGUMENTS, CONFIGURE() use SymfonyComponentConsoleInputInputArgument; protected function configure() { $this->setName('gc:whatTime') ->setDescription('Display the current time.') ->addArgument('date_format', InputArgument::REQUIRED, 'Date format') ; }
  • 21. ARGUMENTS, EXECUTE() $format = $input->getArgument('date_format'); $now = new DateTime(); $output->writeln('It is now ' . $now->format($format) . ', ' . $name);
  • 22. SWITCHES AKA COMMAND OPTIONS Another way to get user input. app$ php govcon.php gc:whatTime --format "H:i:s" What is your name? [Human]: It is now 15:19:31, Human
  • 23. OPTIONS, CONFIGURE use SymfonyComponentConsoleInputInputOption; // earlier // ... $this->setName('gc:whatTime') ->setDescription('Display the current time.') ->setHelp('Print the current time to STDOUT') ->addOption('format', 'f', // shorcut InputOption::VALUE_OPTIONAL, 'Date format' ) ;
  • 24. OPTIONS, EXECUTE $format = $input->getOption('format') ?? 'g:i a'; $now = new DateTime(); $output->writeln( 'It is now ' . $now->format($format) . ', ' . $name );
  • 25. CHOICES AND QUESTIONS Finally, you can let users choose from one or more options. app$ php govcon.php gc:whatTime --format "H:i:s" Which format do you prefer? [military] H:i [common ] g:i a > military It is now 15:27
  • 26. CHOICE, EXECUTE $choices = [ 'military' => 'H:i', 'common' => 'g:i a', ]; $question = new ChoiceQuestion( '<question>Which format do you prefer?</question> ', $choices ); $helper = $this->getHelper('question'); $format = $helper->ask($input, $output, $question); $now = new DateTime(); $output->writeln('It is now ' . $now->format($choices[$format]));
  • 27. CONFIGURATION FILES Use a con guration le to store credentials, or persist values between runs. ->addOption('config', null InputOption::VALUE_REQUIRED, 'Configuration Files' ); $file = $input->getOption('config') ?? '~/govcon.config.php'; $values = $this->readConfig($file); // parse it
  • 28. The format for your config file can be whatever you can parse that is easily writeable by your users. It can be a simple ini file, YAML, json, xml, etc. CREATING A .PHAR
  • 29. A WHAT? A Phar archive is used to distribute a complete PHP application or library in a single le. For the command line, a phar file gives us away to distribute ALL our files inside a single file. The PHP interpreter knows how to work with it. You’re probably already familiar with at least one phar - composer.phar
  • 30. BUILD SKELETON There are multiple ways to build one, I’ll show you how I do it. See also packaging Your Apps with Phar
  • 31. BUILD-PHAR.PHP <?php define ('BASE_SRC', realpath(__DIR__ . '/../app') . '/'); $name = 'govcon.phar'; $app = 'govcon.php'; if (file_exists($name)) { unlink($name); } $phar = new Phar($name, 0, $name); $phar->setSignatureAlgorithm(Phar::SHA1); // add everything under our APP dir $it = new RecursiveIteratorIterator( new RecursiveDirectoryIterator(BASE_SRC, FilesystemIterator::SKIP_DOTS) ); $phar->buildFromIterator($it, BASE_SRC); Explain what this does
  • 32. HAVE YOURSELF A PHAR Once the build comopletes, you’ll have a govcon.phar le. build$ ./govcon.phar gc:whatTime Which format do you prefer? [military] H:i [common ] g:i a > military It is now 15:40 You can share this file with others. Place it somewhere in there $PATH and it’ll be available globally.
  • 33. WORKING WITH FILES In your app le get the path to resources/ and inject it to any comand which needs it. $resource_dir = __DIR__ . '/resources'; $application->add(new FooSomeCommand($resource_dir)); Use DirectoryIterator not glob() to get list of les // copy over resources for this column // phar doesn't support glob $files = new DirectoryIterator($this->resource_dir . "/myfiles/"); foreach ($files as $file) { } If you’re copying files from inside your archive to the user’s file system, use the DirectoryIterorator.
  • 34. THIRD PARTY LIBRARIES Not all libraries may work with bundled les in a phar. In my case, I couldn’t bundle some font files for the Intervention library to use for image manipulation.
  • 35. SECURITY If you need to use api_keys or credentials, don’t put them in your phar le. Use a con guration le and make sure its locked down so only the current user can read it.
  • 36. CONCLUSION Automation can save you time and prevent errors. Symfony Console handles a lot of the plumbing so you can focus on your use case.
  • 37. THANK YOU @omerida I publish php[architect], a monthly magazine for PHP developers. Check it out: www.phparch.com php[world] is our fall conference in Tyson’s Corner. world.phparch.com