📜 ⬆️ ⬇️

PHP console commands

Many, as well as mine, periodically have a need to implement some small tasks. For example, parse the site / API and save the data in xml / json / csv, make any calculations / recalculations, overtake the data from one format to another, collect statistics, etc. etc. I note that we are talking about tasks not related to current projects.



Collecting a heavy framework for the sake of convenient features is too lazy, and it’s somehow not aesthetically pleasing to implement within the code of current projects. Therefore, to save your time, you have to create a script, copy pieces of code from previous developments into it, connect various libraries and run the script from the console. It often requires some interactivity of the script: processing options / arguments, and even interactive interaction. The main thing here is not to have a mood that is well described by the expression “Appetite comes with eating,” then it’s not at all clear what the work on a simple task will lead to =)
')
At such times, I recalled a comfortable symphony console, which I managed to get used to working with projects on
Symfony 2. No offense to other consoles (zend, yii, django, ror etc), everything is good, it just happened.

When once again it was necessary to parse something, I again remembered the Symfony console ( Console Component ) and the fact that this independent component pushed me more and more to the idea of ​​using its capabilities.

For a couple of hours, a simple tool came out , based on:

and Composer dependency manager, which will help us quickly assemble all of this, add new ones, and also take care of autoloading classes.

Suppose we really needed to compile a list of the latest news, “Internet” topics. And as a source, we are quite satisfied with the RSS service Yandex.News.

With the help of Somposer, we create a new project:
$ composer create-project suncat/console-commands ./cmd 

My Composer is installed globally , so it is always available. If you are not using it yet, then you need to install it to check the example.

After downloading the application and all dependencies, go to the created directory:
 $ cd cmd #  ,          

The structure is as follows:
 app/ console #  src/ #  psr-0 Command/ #    vendor/ #   

Check the status:
 $ app/console list 

If we see reference information and a list of available commands, then everything is ok. It looks like this:



Now we will create a template for the class of the team that we plan to use to implement the task:
 $ app/console generate 

In the dialog that appears we indicate the name of the future class:
 Please enter the name of the command class: NewsInternetCommand 

In response, we will receive a notification:
 Generated new command class to "./cmd/src/Command/NewsInternetCommand.php" 

Actually everything, the team is ready, it appeared in the list of available commands:



But so far it does not do what is necessary (here you can open the created class in the IDE or your favorite editor and write the command code).

Since for our example it is necessary to get external content and we like OOP, we will put another library:
 $ composer require kriswallsmith/buzz 0.9 

Buzz is a lightweight HTTP client in PHP5.3. We will use it to make requests to the news service.

Let's create a separate class - YandexRSSNewsParser, which will provide the team with a class of prepared content:
 // ./src/Parser/YandexRSSNewsParser.php namespace Parser; use Buzz\Client\FileGetContents; use Buzz\Message\Request; use Buzz\Message\Response; use DOMDocument; use DOMXPath; class YandexRSSNewsParser { private $method; private $host; /** * Construct */ public function __construct() { $this->method = 'GET'; $this->host = 'http://news.yandex.ru'; } /** * Get news * * @param $resource * * @return mixed */ public function getNews($resource) { // content $xml = $this->getData($resource); if (false === $xml) { return array(); } $doc = new DOMDocument(); @$doc->loadXML($xml); $xpath = new DOMXpath($doc); // items $items = $xpath->query('.//item'); $news = array(); foreach ($items as $item) { $news[] = array( 'datetime' => $xpath->evaluate("./pubDate", $item)->item(0)->nodeValue, 'title' => $xpath->evaluate("./title", $item)->item(0)->nodeValue ); } return $news; } /** * Get data * * @return mixed */ protected function getData($resource) { $request = new Request($this->method, $resource, $this->host); $response = new Response(); $client = new FileGetContents(); // processing get data $attempt = 0; do { if ($attempt) { sleep($attempt); } try { $client->send($request, $response); } catch (\Exception $e) { continue; } } while (false === ($response instanceof Response) && ++$attempt < 5); if (false === ($response instanceof Response) || false === $response->isOk()) { return false; } $data = $response->getContent(); return $data; } } 

And edit the command class to display the latest news headlines in the console, the Internet heading:
 // ./src/Command/NewsInternetCommand.php namespace Command; use Parser\YandexRSSNewsParser; 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; /** * NewsInternetCommand */ class NewsInternetCommand extends Command { /** * Configuration of command */ protected function configure() { $this ->setName("news:internet") ->setDescription("Command for parsing internet news") ; } /** * Execute command * * @param \Symfony\Component\Console\Input\InputInterface $input * @param \Symfony\Component\Console\Output\OutputInterface $output */ protected function execute(InputInterface $input, OutputInterface $output) { $parser = new YandexRSSNewsParser(); $output->writeln("<info>Start parsing</info>\n")); // News $news = $parser->getNews('/internet.rss'); foreach ($news as $item) { $output->writeln(sprintf("<info>[%s]</info> <comment>%s</comment>", $item['datetime'], $item['title'])); } $output->writeln("\n<info>Done!</info>")); } } 

Now execute the prepared command:
 $ app/console news:internet 

Result:


It turned out very simple, but due to symfony / console and composer a flexible and convenient tool for organizing console commands in PHP.

Source: https://habr.com/ru/post/173553/


All Articles