Заканчивая основную часть курса, в последнем уроке мы с вами рассмотрим полноценный класс для отправки запросов в API Яндекс.Диска. Мы упростим весь написанный ранее код и оставим только необходимые методы.

Зная методы и URL для запросов я решил убрать методы которые являются оболочками и обращаться напрямую к методу sendQueryYaDisk().

Так же я решил строку https://cloud-api.yandex.net/v1/disk добавить в свойство $basicApiUrl, а метод sendQueryYaDisk() теперь первым параметром будет принимать не полный URL, а его окончание в котором указываются методы.

Класс для работы с Яндекс.Диск через API


class Backup
{
    protected $token = 'токен';
    protected $basicApiUrl = 'https://cloud-api.yandex.net/v1/disk/';

    /**
     * Method sendQueryYaDisk
     *
     * @param string $urlQuery URL для отправки запросов
     * @param array $arrQuery массив параметров
     * @param string $methodQuery метод отправки
     *
     * @return array
     */
    public function sendQueryYaDisk(string $methodAPI = '', array $arrQuery = [], string $methodQuery = 'GET'): array
    {
        if($methodQuery == 'POST') {
            $fullUrlQuery = $this->basicApiUrl . $methodAPI;
        } else {
            $fullUrlQuery = $this->basicApiUrl . $methodAPI . '?' . http_build_query($arrQuery);
        }

        $ch = curl_init($fullUrlQuery);
        switch ($methodQuery) {
            case 'PUT':
                curl_setopt($ch, CURLOPT_PUT, true);
                break;

            case 'POST':
                curl_setopt($ch, CURLOPT_POST, 1);
	            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($arrQuery));
                break;

            case 'DELETE':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
                break;
        }

        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: OAuth ' . $this->token]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HEADER, false);
        $resultQuery = curl_exec($ch);
        curl_close($ch);

        return (!empty($resultQuery)) ? json_decode($resultQuery, true) : [];
    }


    
    /**
     * Метод для загрузки файлов
     *
     * @param string $filePath путь до файла
     * @param string $dirPath путь до директории на Яндекс.Диск
     *
     * @return string
     */
    public function disk_resources_upload(string $filePath, string $dirPath = ''): string
    {
        $arrParams = [
            'path' => $dirPath . basename($filePath),
            'overwrite' => 'true',
        ];

        $urlQuery = 'https://cloud-api.yandex.net/v1/disk/resources/upload';
        $resultQuery = $this->sendQueryYaDisk('resources/upload', $arrParams);

        if (empty($resultQuery['error'])) {
            $fp = fopen($filePath, 'r');
        
            $ch = curl_init($resultQuery['href']);
            curl_setopt($ch, CURLOPT_PUT, true);
            curl_setopt($ch, CURLOPT_UPLOAD, true);
            curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath));
            curl_setopt($ch, CURLOPT_INFILE, $fp);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_HEADER, false);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
        
            return $http_code;
        } else {
            return $resultQuery['message'];
        }
    }
    

    
    /**
     * Метод для скачивания файлов на сервера
     *
     * @param string $filePath путь до файла в Яндекс.Диске
     * @param string $dirPath путь до директории на сервере
     *
     * @return array
     */
    public function disk_resources_download(string $filePath, string $dirPath = ''): array
    {
        $arrParams = [
            'path' => $filePath,
        ];
        $resultQuery = $this->sendQueryYaDisk('resources/download', $arrParams);

        if(empty($resultQuery['error'])) {
            $file_name = $dirPath . basename($filePath);
            $file = @fopen($file_name, 'w');
        
            $ch = curl_init($resultQuery['href']);
            curl_setopt($ch, CURLOPT_FILE, $file);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: OAuth ' . $this->token));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_HEADER, false);
            $resultQuery = curl_exec($ch);
            curl_close($ch);

            fclose($file);

            return [
                'message' => 'Файл успешно загружен',
                'path' => $file_name,
            ];
        } else {
            return $resultQuery;
        }
    }
    

}

Получения общей информации об аккаунте Яндекс.Диска через API

$resultQuery = $backupClass->sendQueryYaDisk();

Получение метаинформации о папках и файлах на Яндекс.Диске через API

$arrParams = [
    'path' => '/uploads',
    'fields' => 'name,_embedded.items.path',
    'limit' => 100,
    'offset' => 0,
    'preview_crop' => false,
    'preview_size' => '',
    'sort' => 'created'
];
$resultQuery = $backupClass->sendQueryYaDisk('resources', $arrParams);

Получение метаинформации о папках и файлах в корзине на Яндекс.Диске через API

$arrParams = [
    'path' => '/',
    'fields' => 'name,_embedded.items.path',
    'limit' => 100,
    'offset' => 0,
    'preview_crop' => false,
    'preview_size' => '',
    'sort' => 'created'
];
$resultQuery = $backupClass->sendQueryYaDisk('trash/resources', $arrParams);

Получение плоского списка всех файлов с Яндекс.Диска через API

$arrParams = [
    'limit' => 100,
    'media_type' => 'image',
    'offset' => 0,
    'fields' => 'name,_embedded.items.path',
    'preview_size' => '',
    'preview_crop' => false,
];
$resultQuery = $backupClass->sendQueryYaDisk('resources/files', $arrParams);

Получение последних загруженных элементов на Яндекс.Диск через API

$arrParams = [
    'limit' => 10,
    'media_type' => 'image',
    'fields' => 'name,_embedded.items.path',
    'preview_size' => '',
    'preview_crop' => false,
];
$resultQuery = $backupClass->sendQueryYaDisk('resources/last-uploaded', $arrParams);

Метод для создания директории на Яндекс.Диске через API

$arrParams = [
    'path' => '/uploads/prog_time',
    'fields' => 'name,_embedded.items.path',
];
$resultQuery = $backupClass->sendQueryYaDisk('resources', $arrParams, 'PUT');

Метод для загрузки файлов на Яндекс.Диск через API

$filePath = $_SERVER['DOCUMENT_ROOT'] . '/public/image.png';
$dirPath = '/uploads';
$resultQuery = $backupClass->disk_resources_upload($filePath, $dirPath);

Метод для скачивания файлов с Яндекс.Диска на сервера через API

$filePath = '/test.docx';
$dirPath = $_SERVER['DOCUMENT_ROOT'] . '/public';
$resultQuery = $backupClass->disk_resources_download($filePath, $dirPath);

Удаление ресурса с Яндекс.Диск через API

$arrParams = [
    'path' => '/test.docx',
    'permanently' => false,
    'fields' => 'name,_embedded.items.path',
];
$resultQuery = $backupClass->sendQueryYaDisk('resources', $arrParams, 'DELETE');

Публикация файла в Яндекс.Диске через API

$arrParams = [
    'path' => '/uploads/test.xlsx',
];
$resultQuery = $backupClass->sendQueryYaDisk('resources/publish', $arrParams, 'PUT');

Снятие с публикации файла в Яндекс.Диске через API

$arrParams = [
    'path' => '/uploads/test.xlsx',
];
$resultQuery = $backupClass->sendQueryYaDisk('resources/unpublish', $arrParams, 'PUT');

Получение списка публичных файлов с Яндекс.Диска через API

$arrParams = [
    'limit' => 10,
    'offset' => 0,
    'type' => 'dir',
    'fields' => 'name,_embedded.items.path',
    'preview_size' => '',
];
$resultQuery = $backupClass->sendQueryYaDisk('resources/public', $arrParams);

Метод для востановления файла из корзины в Яндекс.Диске через API

$arrParams = [
    'path' => 'trash:/test.docx_f8fb153e7cb73695ee2fdada79a7871b0093596e',
    'name' => 'new_name.docx'
];
$resultQuery = $backupClass->sendQueryYaDisk('trash/resources/restore', $arrParams, 'PUT');

Очистка корзины в Яндекс.Диске через API

$resultQuery = $backupClass->sendQueryYaDisk('trash/resources', [], 'DELETE');

Комментарии (10)


  1. hierarchical
    20.07.2023 18:49
    -5

    А есть примеры для питона и гоу? А то в интернетах информации совсем нету. Отличная статья, спс.


  1. FanatPHP
    20.07.2023 18:49
    +3

    Когда вдруг внезапно вспомнил, что давно не продвигал свой сайт на Хабре.


  1. smind
    20.07.2023 18:49
    -8

    типа это минусуют статьи? увидев красноту пролистал вроде слог нормальный, без особой фигни. php не моя тема конечно, но кому-то может интересно. Удивился короче.


    1. dopusteam
      20.07.2023 18:49
      +3

      Вроде есть более подходящие сайты, чтоб кодом делиться

      А ещё оказалось, что автор напилил аж шесть статей такого формата, одну за другой


      1. smind
        20.07.2023 18:49
        -6

        тоже заметил, но ничего такого прям вызывающего.


    1. FanatPHP
      20.07.2023 18:49
      +11

      Дело не в слоге (хотя он довольно корявый), а в количестве. Пока он выкладывал свои творения по одному, их терпели. Но вывалить всё кучей, заспамив людям ленту — это уже перебор. Учитывая, что это не супер-эксклюзивный контент, а ученические потуги, которым и так-то не факт, что место на Хабре.


      1. smind
        20.07.2023 18:49
        +3

        понял.


  1. Metotron0
    20.07.2023 18:49
    +1

    Я бы сказал, что в первом блоке кода $fullUrlQuery = $this->basicApiUrl . $methodAPI можно не дублировать, а ввнести из-под условия.

    В disk_resources_upload почему-то опять путь написан целиком. И он вроде даже не используется.

    // Копипастил телефоном, не понял, как тут переключиться в режим bb-кодов и убрать мои слова из цитат кода.


    1. Metotron0
      20.07.2023 18:49
      +1

      Ещё добавлю, что если в if есть return, то else писать не обязательно.

      А если else состоит из одной строчки, то возможно, лучше будет инвертировать условие, перенести else в if, а то, что раньше было в if, уменьшит свой уровень вложенности, код станет более линейным. Гуглить "ранний возврат".

      Почему-то после if перед скобкой то есть пробел, то его нет.


  1. Gitya_Man
    20.07.2023 18:49
    +6

    1) токен захардкожен, почему не передать через конструктор?
    2) яндекс.диск это хранилище, зачем его реализация нужна в классе бэкапа? Почему вообще класс бэкапа имеет публичный метод отправки запроса в Яндекс? Может это клиент тогда, а не бэкап? Создать интерфейс провайдера и имплементировать яндекс, было бы логичнее.
    3) один метод в camelCase, второй в snake_case
    4)$backupClass - это не класс, а объект
    5) оператор подавления ошибок @ не стоит использовать в подавляющем большинстве случаев, в том числе в Вашем.
    6) PHPDoc где-то на русском, где-то на английском и содержит в себе те вещи, которые непременно устареют, а что важнее в принципе не несут смысловой нагрузки.

    >Заканчивая основную часть курса
    > в последнем уроке

    Чтобы чему-то учить, было бы неплохо научиться самому. Я не понял что автор хочет донести до читателя, какова цель этой статьи?
    Если цель показать как делать не нужно, то она достигнута.
    Зачем эту статью было делить на 5(!) частей мне тоже совершенно непонятно?

    Ознакомьтесь с PSR стандартами, прочитайте что-нибудь вроде Мартин Р. С.: Чистый код