Многие люди считают что php подходит только для разработки сайтиков, и никак не может быть использован, в других областях применения языков программирования, для создания программ… В этой статье я бы хотел осветить, применение php скриптов «не целевым» образом, а именно мы напишем скрипт который будет делать скрин, выгружать его на yandex диск и выводить адрес скриншота в консоль…
Рассмотрим структуру проекта, она очень проста и состоит из 3-х файлов:
1. screen.php — точка входа в приложение.
2. classes/autoload.php — автолоадер проекта.
3. classes/Request.php — класс реализующий запросы к api яндекса.
Далее расмотрим код screen.php:
Как видите это точка входа в приложение, логика проста:
1. Формирование имени скриншота
2. Вызов системной программы scrot
3. Запрос api yandex.disk и выгрузка скриншота
Файл autoload.php тоже очень прост и состоит всего из трёх строк кода, я приведу его лишь для ознакомления, и мы не будем его рассматривать подробно.
Работа с yandex api довольно проста я написал небольшой класс Request.php, с набором неких методов, которые помогают мне в работе с ним…
Рассмотрим ключевые методы данного класса для запроса методов api в основном я использовал file_get_contents, и так как мне приходилось использовать, его при запросе многих методов я написал метод генерации контекста:
Он тоже довольно прост мы создаём контекст с определённом методом запроса и информации об аутентификации…
Далее нам необходимо «создать файл на yandex.disk» это действие мы производим следующим методом:
Как я говорил ранее мы запрашиваем api с помощью функции file_get_contents. После того как этот метод отработает, и вся информация будет запрошена, запускаеться метод upload:
В данно случае можно было бы использовать для отправки файла одну из функций `file_get_contents` или `file_put_contents` но это не целесообразно, по причине того что пришлось бы, в контексте данных функций, в ручную имитировать заголовки и другие вытекающие из этого проблемы, так что проще просто использовать для этих целей curl.
И так файл загружен, остаёться только опубликовать его и получить прямую ссылку для просмотра, это выполняет функция publicateFile():
В этом методе тоже всё довольно просто, мы запрашиваем публикацию файла методом PUT у api, яндекс возвращает ссылку, на которую мы должны выполнить запрос для подтвержедения публикации, и метод запроса в диску. И в конце концов, после второго запроса мы получаем массив который соддержит ссылку на публичный файл.
Чтож мы закончили, теперь нам предстоит придумать а как же этот скрипт будет работать из консоли? как его запустить там в «глобальной области»? ответом на эти вопросы будет phar — архив содержащий файлы php и способный выполняться как отдельное приложение, похож на тот же jar.
phar мы будем собирать с помощью утилиты box.phar для этого мы пишем простой конфигурационный файл box.json:
Для сборки запускаем:
И наш проект готов теперь осталось только установить права на исполнение файла, и скопировать в директорию /usr/bin/srcphp:
Не забываем о конфигурации файла /home/myname/.config/srcphp/config.php:
в token необходимо вписать полученный oAuth токен от яндекса, при переходе сгенерированной по средством запуска скрипта с ключом --getToken:
Главная мысль статьи — рассмотреть как создать консольное приложение с помощью php, на примере программы скриншотера, в следующих я буду поднимать тему использования php в различных сферах применения, и следующая статью будет посвящена разработки простого драйвера usb устройства для linux. Спасибо за внимание и доброго дня.
p.s. Исходный код приложения
Рассмотрим структуру проекта, она очень проста и состоит из 3-х файлов:
1. screen.php — точка входа в приложение.
2. classes/autoload.php — автолоадер проекта.
3. classes/Request.php — класс реализующий запросы к api яндекса.
Далее расмотрим код screen.php:
Код screen.php
#!/usr/bin/php
<?php
require_once('classis/autoload.php');
$request = new Request();
if(isset($argv[1]) && $argv[1] == '--getToken') {
echo $request->getOauthLink();die;
}
$home = $_SERVER['HOME'];
$config = include($home . '/.config/scrphp/config.php');
$nameScreenshot = date('Y_m_d_G_i_s_') . 'screen.png';
system('scrot -s /tmp/'.$nameScreenshot);
$result = $request
->setToken($config['token'])
->setFileNameOnDisk($nameScreenshot)
->setPathToFile('/tmp/'.$nameScreenshot)
->upload()
->publicateFile();
$url = $result['public_url'];
echo $url.PHP_EOL;
Как видите это точка входа в приложение, логика проста:
1. Формирование имени скриншота
2. Вызов системной программы scrot
3. Запрос api yandex.disk и выгрузка скриншота
Файл autoload.php тоже очень прост и состоит всего из трёх строк кода, я приведу его лишь для ознакомления, и мы не будем его рассматривать подробно.
spl_autoload_register(function($name){
require_once __DIR__.'/'.$name.'.php';
});
Работа с yandex api довольно проста я написал небольшой класс Request.php, с набором неких методов, которые помогают мне в работе с ним…
Листинг Request.php
<?php
class Request
{
private $_token = null;
private $_href = null;
private $_method = null;
private $_filePath = null;
private $_fileName = null;
/**
* get oauth link
*/
public function getOauthLink()
{
/**
* https://oauth.yandex.ru/authorize?
* response_type=token
* & client_id=<идентификатор приложения>
* [& device_id=<идентификатор устройства>]
* [& device_name=<имя устройства>]
* [& display=popup]
* [& login_hint=<имя пользователя или электронный адрес>]
* [& force_confirm=yes]
* [& state=<произвольная строка>]
*/
$link = 'https://oauth.yandex.ru/authorize'
.'?response_type=token'
. '&client_id=8fc231e60575439fafcdb3b9281778a3';
echo $link;
}
/**
* set file path on disk
* @param $filePath
* @return $this
*/
public function setFileNameOnDisk($name)
{
/**
* https://cloud-api.yandex.net/v1/disk/resources/upload ?
* path=<путь, по которому следует загрузить файл>
*/
$link = 'https://cloud-api.yandex.net/v1/disk/resources/upload?path='.urlencode('/'.trim($name,'/'));
$response = file_get_contents($link,false,$this->_context('GET'));
$responseAsArray = json_decode($response,true);
$this->_href = $responseAsArray['href'];
$this->_method = $responseAsArray['method'];
$this->_fileName = $name;
return $this;
}
/**
* get path to file on local disk
* @param $path
* @return $this
*/
public function setPathToFile($path) {
$this->_filePath = $path;
return $this;
}
/**
* upload file to disk
*/
public function upload()
{
$ch = curl_init($this->_href);
curl_setopt($ch,CURLOPT_HTTPHEADER,
array(
'Authorization',
'OAuth '.$this->_token
)
);
curl_setopt($ch,CURLOPT_INFILE,fopen($this->_filePath,"r"));
curl_setopt($ch,CURLOPT_INFILESIZE,filesize($this->_filePath));
curl_setopt($ch,CURLOPT_PUT,true);
curl_exec($ch);
curl_close($ch);
return $this;
}
/**
* public file and get public url for screenshot
* @return mixed
*/
public function publicateFile()
{
/**
* https://cloud-api.yandex.net/v1/disk/resources/publish ?
* path=<путь к публикуемому ресурсу>
*/
$link = 'https://cloud-api.yandex.net/v1/disk/resources/publish?path='.urlencode('/'.trim($this->_fileName,'/'));
$response = file_get_contents($link,false,$this->_context('PUT'));
$responseAsArray = json_decode($response,true);
$publicateFile = file_get_contents($responseAsArray['href'],false,$this->_context($responseAsArray['method']));
$publicateFileAsArray = json_decode($publicateFile,true);
return $publicateFileAsArray;
}
/**
* set oauth token
* @param $key
* @return $this
*/
public function setToken($token)
{
$this->_token = $token;
return $this;
}
/**
* get context for request by file_get_contents
* @param $method
* @return resource
*/
private function _context($method)
{
/**
* Authorization: OAuth <key>
*/
$opts = array(
'http'=>array(
'method'=>$method,
'header'=>"Authorization: OAuth ".$this->_token."\r\n"
)
);
$context = stream_context_create($opts);
return $context;
}
}
Рассмотрим ключевые методы данного класса для запроса методов api в основном я использовал file_get_contents, и так как мне приходилось использовать, его при запросе многих методов я написал метод генерации контекста:
/**
* get context for request by file_get_contents
* @param $method
* @return resource
*/
private function _context($method)
{
/**
* Authorization: OAuth <key>
*/
$opts = array(
'http'=>array(
'method'=>$method,
'header'=>"Authorization: OAuth ".$this->_token."\r\n"
)
);
$context = stream_context_create($opts);
return $context;
}
Он тоже довольно прост мы создаём контекст с определённом методом запроса и информации об аутентификации…
Далее нам необходимо «создать файл на yandex.disk» это действие мы производим следующим методом:
/**
* set file path on disk
* @param $filePath
* @return $this
*/
public function setFileNameOnDisk($name)
{
/**
* https://cloud-api.yandex.net/v1/disk/resources/upload ?
* path=<путь, по которому следует загрузить файл>
*/
$link = 'https://cloud-api.yandex.net/v1/disk/resources/upload?path='.urlencode('/'.trim($name,'/'));
$response = file_get_contents($link,false,$this->_context('GET'));
$responseAsArray = json_decode($response,true);
$this->_href = $responseAsArray['href'];
$this->_method = $responseAsArray['method'];
$this->_fileName = $name;
return $this;
}
Как я говорил ранее мы запрашиваем api с помощью функции file_get_contents. После того как этот метод отработает, и вся информация будет запрошена, запускаеться метод upload:
/**
* upload file to disk
*/
public function upload()
{
$ch = curl_init($this->_href);
curl_setopt($ch,CURLOPT_HTTPHEADER,
array(
'Authorization',
'OAuth '.$this->_token
)
);
curl_setopt($ch,CURLOPT_INFILE,fopen($this->_filePath,"r"));
curl_setopt($ch,CURLOPT_INFILESIZE,filesize($this->_filePath));
curl_setopt($ch,CURLOPT_PUT,true);
curl_exec($ch);
curl_close($ch);
return $this;
}
В данно случае можно было бы использовать для отправки файла одну из функций `file_get_contents` или `file_put_contents` но это не целесообразно, по причине того что пришлось бы, в контексте данных функций, в ручную имитировать заголовки и другие вытекающие из этого проблемы, так что проще просто использовать для этих целей curl.
И так файл загружен, остаёться только опубликовать его и получить прямую ссылку для просмотра, это выполняет функция publicateFile():
/**
* public file and get public url for screenshot
* @return mixed
*/
public function publicateFile()
{
/**
* https://cloud-api.yandex.net/v1/disk/resources/publish ?
* path=<путь к публикуемому ресурсу>
*/
$link = 'https://cloud-api.yandex.net/v1/disk/resources/publish?path='.urlencode('/'.trim($this->_fileName,'/'));
$response = file_get_contents($link,false,$this->_context('PUT'));
$responseAsArray = json_decode($response,true);
$publicateFile = file_get_contents($responseAsArray['href'],false,$this->_context($responseAsArray['method']));
$publicateFileAsArray = json_decode($publicateFile,true);
return $publicateFileAsArray;
}
В этом методе тоже всё довольно просто, мы запрашиваем публикацию файла методом PUT у api, яндекс возвращает ссылку, на которую мы должны выполнить запрос для подтвержедения публикации, и метод запроса в диску. И в конце концов, после второго запроса мы получаем массив который соддержит ссылку на публичный файл.
Установка скрипта
Чтож мы закончили, теперь нам предстоит придумать а как же этот скрипт будет работать из консоли? как его запустить там в «глобальной области»? ответом на эти вопросы будет phar — архив содержащий файлы php и способный выполняться как отдельное приложение, похож на тот же jar.
phar мы будем собирать с помощью утилиты box.phar для этого мы пишем простой конфигурационный файл box.json:
{
"files": [
"classis/autoload.php",
"classis/Request.php",
"screen.php"
],
"main": "screen.php",
"output": "srcphp.phar",
"stub": true
}
Для сборки запускаем:
$ php box.phar build
И наш проект готов теперь осталось только установить права на исполнение файла, и скопировать в директорию /usr/bin/srcphp:
$ chmod +x srcphp.phar
$ cp srcphp.phar /usr/bin/srcphp
Не забываем о конфигурации файла /home/myname/.config/srcphp/config.php:
<?php
// copy this file to /home/user/.config/srcphp/config.php
return array(
'token' => 'your token'
);
в token необходимо вписать полученный oAuth токен от яндекса, при переходе сгенерированной по средством запуска скрипта с ключом --getToken:
$ srcphp --getToken
Выводы
Главная мысль статьи — рассмотреть как создать консольное приложение с помощью php, на примере программы скриншотера, в следующих я буду поднимать тему использования php в различных сферах применения, и следующая статью будет посвящена разработки простого драйвера usb устройства для linux. Спасибо за внимание и доброго дня.
p.s. Исходный код приложения