Рубрики
Uncategorized

Подробные инструкции по разработке пакетов Composer

Автор оригинала: David Wong.

Разработайте универсальный пакет для загрузки файлов composer, опубликуйте его в Packagist и протестируйте в Laravel.

Сначала GitHub создает новое хранилище с именем Файл загрузки и клонирует его локально.

$ git clone [email protected]github.com:guanguans/uploadfile.git
$ cd uploadfile

2. Инициализируйте проект и сгенерируйте файл composer.json

2.1 шаги

[email protected] MINGW64 /i/phpstudy/WWW/uploadfile
$ composer init


  Welcome to the Composer config generator



This command will guide you through creating your composer.json config.

Package name (/) [yzm/try-make-package]: guanguans/uploadfile
Description []: A generic file upload package
Author [guanguans <[email protected]>, n to skip]: guanguans <[email protected]>                                                                                 
Minimum Stability []: dev
Package Type (e.g. library, project, metapackage, composer-plugin) []: l                                                                                                    ibrary
License []: MIT

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]                                                                                                    ? yes
Search for a package: php
Enter the version constraint to require (or leave blank to use the lates                                                                                                    t version): >=5.4.0
Search for a package:
Would you like to define your dev dependencies (require-dev) interactive                                                                                                    ly [yes]? yes
Search for a package: php
Enter the version constraint to require (or leave blank to use the lates                                                                                                    t version): >=5.4.0
Search for a package:

{
    "name": "guanguans/uploadfile",
    Description: "A generic file upload package"
    "type": "library",
    "require": {
        "php": ">=5.4"
    },
    "require-dev": {
        "php": ">=5.4"
    },
    "license": "MIT",
    "authors": [
        {
            "name": "guanguans",
            "email": "[email protected]"
        }
    ],
    "minimum-stability": "dev"
}

Do you confirm generation [yes]? yes

2.2 Объяснение шага

[email protected] MINGW64 /i/phpstudy/WWW/uploadfile
$ composer init


  Welcome to the Composer config generator



This command will guide you through creating your composer.json config.

// 1. Enter the project namespace
// Note that / must conform to [a-z0-9_. -]+/[a-z0-9_. -]+
Package name (/) [dell/htdocs]: yourname/projectname

// 2. Project description
Description []: This is a test

// 3. Enter the author's information, you can return directly.
Author [guanguans <[email protected]>, n to skip]:

// 4. Enter the lowest stable version, stable, RC, beta, alpha, dev
Minimum Stability []: dev

// 5. Enter the project type.
Package Type (e.g. library, project, metapackage, composer-plugin) []: library

// 6. Enter the type of authorization
License []:
> Define your dependencies.

// 7. Input dependency information
Would you like to define your dependencies (require) interactively [yes]?

// If dependencies are required, enter the dependencies to be installed
Search for a package: php

// Enter version number
Enter the version constraint to require (or leave blank to use the latest version): >=5.4.0

// If more than one is needed, repeat the above two steps

// 8. Is it necessary to require-dev?
Would you like to define your dev dependencies (require-dev) interactively [yes]?

// Operations Ibid.
{
    "name": "guanguans/uploadfile",
    Description: "A generic file upload package"
    "type": "library",
    "require": {
        "php": ">=5.4"
    },
    "require-dev": {
        "php": ">=5.4"
    },
    "license": "MIT",
    "authors": [
        {
            "name": "guanguans",
            "email": "[email protected]"
        }
    ],
    "minimum-stability": "dev"
}

// 9. Whether to generate composer. JSON
Do you confirm generation [yes]? yes

3. Добавление Автоматической Загрузки

Сгенерировано на предыдущем шаге composer.json Вторичное добавление

"autoload": {
    "psr-4": {
        "Guanguans\\": "src/"
    }
}

IV. Строительные Проекты

4.1 NEWuploadfile/src/UploadFile.php

├─uploadfile                
│  ├─src                     
│  │  ├─UploadFile.php
│  └─composer.json
[email protected]>
 */
Namespace Guanguans; // Note that namespaces are consistent with composer. JSON

class UploadFile
{
    private $config = [   
        'maxSize'=>-1, //maximum upload file
        'Support Multi'=> true, /// Supporting multi-file upload
        'allowExts'=> [], // File suffixes allowed to upload are left blank without suffix checking
        'allowTypes'=> [], // File type allowed to upload is left blank and unchecked
        'thumb'=> false, // thumbnail the uploaded image
        'imageClassPath'=>'ORG.Util.Image', //gallery class package path
        'thumbMaxWidth'=>', //thumbnail maximum width
        'thumbMaxHeight'=>', //thumbnail maximum height
        'thumbPrefix'=>'thumb_', //thumbnail prefix
        'thumbSuffix'       =>  '',
        'thumbPath'=>', //thumbnail save path
        'thumbFile'=>', //thumbnail file name
        'thumbExt'=>', //thumbnail extension
        'thumbRemove Origin'=> false, // Remove the original image
        'thumbType'=> 1, // thumbnail generation mode 1, intercept 0 according to the size of the settings, and abbreviate in equal proportion to the original image
        'zipImages'=> false, //compressed picture file upload
        'autoSub'=> false, // Enable subdirectories to save files
        'SubType'=>'hash', //subdirectory creation can use hash date custom
        SubDir'=>', //subdirectory name subType is valid after custom mode
        'dateFormat'        =>  'Ymd',
        'hashLevel'=> 1, // hash directory hierarchy
        'savePath'=>', // Upload File Save Path
        'autoCheck'=> true, /// whether to automatically check attachments
        'uploadReplace'=> false, // whether the same name is overwritten
        'saveRule'=>'uniqid', //Upload File Naming Rules
        'hashType'=>'md5_file', //Upload file Hash rule function name
    ];

    // Error message
    private $error = '';
    // Upload Successful File Information
    private $uploadFileInfo ;

    public function __get($name){
        if(isset($this->config[$name])) {
            return $this->config[$name];
        }
        return null;
    }

    public function __set($name,$value){
        if(isset($this->config[$name])) {
            $this->config[$name]    =   $value;
        }
    }

    public function __isset($name){
        return isset($this->config[$name]);
    }

    /**
     * Architectural functions
     * @access public
     *@ Param array $config upload parameter
     */
    public function __construct($config=[]) {
        if(is_array($config)) {
            $this->config   =   array_merge($this->config,$config);
        }
    }

    /**
     * Upload a file
     * @access public
     *@ Param mixed $name data
     *@ Param string $value data table name
     * @return string
     */
    private function save($file) {
        $filename = $file['savepath'].$file['savename'];
        if(!$this->uploadReplace && is_file($filename)) {
            // Documents with the same name are not overwritten
            This - > error = file already exists! '.$filename;
            return false;
        }
        // If it is an image file, check the file format
        if( in_array(strtolower($file['extension']), ['gif','jpg','jpeg','bmp','png','swf'])) {
            $info   = getimagesize($file['tmp_name']);
            if(false === $info || ('gif' == strtolower($file['extension']) && empty($info['bits']))){
                $this - > error = illegal image file;
                return false;
            }
        }
        if(!move_uploaded_file($file['tmp_name'], $this->autoCharset($filename,'utf-8','gbk'))) {
            This - > error = file upload save error! ';
            return false;
        }
        if($this->thumb && in_array(strtolower($file['extension']), ['gif','jpg','jpeg','bmp','png'])) {
            $image =  getimagesize($filename);
            if(false !== $image) {
                // Generate thumbnails for image files
                $thumbWidth        =    explode(',',$this->thumbMaxWidth);
                $thumbHeight    =    explode(',',$this->thumbMaxHeight);
                $thumbPrefix    =    explode(',',$this->thumbPrefix);
                $thumbSuffix    =   explode(',',$this->thumbSuffix);
                $thumbFile        =    explode(',',$this->thumbFile);
                $thumbPath      =   $this->thumbPath?$this->thumbPath:dirname($filename).'/';
                $thumbExt = this - > thumbExt? $this - > thumbExt: $file ['extension']; // custom thumbnail extension
                // Generating image thumbnails
                import($this->imageClassPath);
                for($i=0,$len=count($thumbWidth); $i<$len; $i++) {
                    if(!empty($thumbFile[$i])) {
                        $thumbname  =   $thumbFile[$i];
                    }else{
                        $prefix     =   isset($thumbPrefix[$i])?$thumbPrefix[$i]:$thumbPrefix[0];
                        $suffix     =   isset($thumbSuffix[$i])?$thumbSuffix[$i]:$thumbSuffix[0];
                        $thumbname  =   $prefix.basename($filename,'.'.$file['extension']).$suffix;
                    }
                    if(1 == $this->thumbType){
                        Image::thumb2($filename,$thumbPath.$thumbname.'.'.$thumbExt,'',$thumbWidth[$i],$thumbHeight[$i],true);
                    }else{
                        Image::thumb($filename,$thumbPath.$thumbname.'.'.$thumbExt,'',$thumbWidth[$i],$thumbHeight[$i],true);
                    }

                }
                if($this->thumbRemoveOrigin) {
                    // Delete the original image after generating thumbnails
                    unlink($filename);
                }
            }
        }
        if($this->zipImags) {
            // TODO on-line decompression of picture compression packages

        }
        return true;
    }

    /**
     * Upload all files
     * @access public
     *@ Param string $savePath upload file save path
     * @return string
     */
    public function upload($savePath ='') {
        // If the save file name is not specified, the system defaults
        if(empty($savePath))
            $savePath = $this->savePath;
        // Check the upload directory
        if(!is_dir($savePath)) {
            // Check if the directory is coded
            if(is_dir(base64_decode($savePath))) {
                $savePath    =    base64_decode($savePath);
            }else{
                // Try to create a directory
                if(!mkdir($savePath)){
                    $this - > error = upload directory'. $savePath.'None exists';
                    return false;
                }
            }
        }else {
            if(!is_writeable($savePath)) {
                $this - > error = upload directory'. $savePath.'Unwritable';
                return false;
            }
        }
        $fileInfo   = [];
        $isUpload   = false;

        // Get Uploaded File Information
        // Information Processing for $_FILES Array
        $files     =     $this->dealFiles($_FILES);
        foreach($files as $key => $file) {
            // Filling Invalid Uploads
            if(!empty($file['name'])) {
                // Extended information for registering uploaded files
                if(!isset($file['key']))   $file['key']    =   $key;
                $file['extension']  =   $this->getExt($file['name']);
                $file['savepath']   =   $savePath;
                $file['savename']   =   $this->getSaveName($file);

                // Automatic inspection of accessories
                if($this->autoCheck) {
                    if(!$this->check($file))
                        return false;
                }

                // Save uploaded files
                if(!$this->save($file)) return false;
                if(function_exists($this->hashType)) {
                    $fun =  $this->hashType;
                    $file['hash']   =  $fun($this->autoCharset($file['savepath'].$file['savename'],'utf-8','gbk'));
                }
                // After successful upload, save file information for call elsewhere
                unset($file['tmp_name'],$file['error']);
                $fileInfo[] = $file;
                $isUpload   = true;
            }
        }
        if($isUpload) {
            $this->uploadFileInfo = $fileInfo;
            return true;
        }else {
            $this - > error ='No upload file selected';
            return false;
        }
    }

    /**
     * Supporting multiple attachments by uploading files in a single upload field
     * @access public
     *@ Param array $file uploads file information
     *@ Param string $savePath upload file save path
     * @return string
     */
    public function uploadOne($file,$savePath=''){
        // If the save file name is not specified, the system defaults
        if(empty($savePath))
            $savePath = $this->savePath;
        // Check the upload directory
        if(!is_dir($savePath)) {
            // Try to create a directory
            if(!mkdir($savePath,0777,true)){
                $this - > error = upload directory'. $savePath.'None exists';
                return false;
            }
        }else {
            if(!is_writeable($savePath)) {
                $this - > error = upload directory'. $savePath.'Unwritable';
                return false;
            }
        }
        // Filling Invalid Uploads
        if(!empty($file['name'])) {
            $fileArray = [];
            if(is_array($file['name'])) {
               $keys = array_keys($file);
               $count     =     count($file['name']);
               for ($i=0; $i<$count; $i++) {
                   foreach ($keys as $key)
                       $fileArray[$i][$key] = $file[$key][$i];
               }
            }else{
                $fileArray[] =  $file;
            }
            $info =  [];
            foreach ($fileArray as $key=>$file){
                // Extended information for registering uploaded files
                $file['extension']  = $this->getExt($file['name']);
                $file['savepath']   = $savePath;
                $file['savename']   = $this->getSaveName($file);
                // Automatic inspection of accessories
                if($this->autoCheck) {
                    if(!$this->check($file))
                        return false;
                }
                // Save uploaded files
                if(!$this->save($file)) return false;
                if(function_exists($this->hashType)) {
                    $fun =  $this->hashType;
                    $file['hash']   =  $fun($this->autoCharset($file['savepath'].$file['savename'],'utf-8','gbk'));
                }
                unset($file['tmp_name'],$file['error']);
                $info[] = $file;
            }
            // Return uploaded file information
            return $info;
        }else {
            $this - > error ='No upload file selected';
            return false;
        }
    }

    /**
     * Converting Upload File Array Variables to the Right Way
     * @access private
     *@ File variables uploaded by param array $files
     * @return array
     */
    private function dealFiles($files) {
        $fileArray  = [];
        $n          = 0;
        foreach ($files as $key=>$file){
            if(is_array($file['name'])) {
                $keys       =   array_keys($file);
                $count      =   count($file['name']);
                for ($i=0; $i<$count; $i++) {
                    $fileArray[$n]['key'] = $key;
                    foreach ($keys as $_key){
                        $fileArray[$n][$_key] = $file[$_key][$i];
                    }
                    $n++;
                }
            }else{
               $fileArray[$key] = $file;
            }
        }
       return $fileArray;
    }

    /**
     * Get error code information
     * @access public
     *@ Param string $errorNo error number
     * @return void
     */
    protected function error($errorNo) {
         switch($errorNo) {
            case 1:
                $this - > error = the uploaded file exceeds the limit of the upload_max_filesize option in php.ini';
                break;
            case 2:
                The size of the uploaded file exceeds the value specified by the MAX_FILE_SIZE option in the HTML form.
                break;
            case 3:
                This - > error ='Only part of the file is uploaded';
                break;
            case 4:
                $this - > error = no file uploaded';
                break;
            case 6:
                $this - > error ='temporary folder not found';
                break;
            case 7:
                $this - > error = file write failure;
                break;
            default:
                This - > error = Unknown upload error! ';
        }
        return ;
    }

    /**
     * Get the saved file name according to the upload file naming rules
     * @access private
     *@ Param string $filename data
     * @return string
     */
    private function getSaveName($filename) {
        $rule = $this->saveRule;
        If (empty ($rule) {// no naming rules are defined, the file name remains unchanged
            $saveName = $filename['name'];
        }else {
            if(function_exists($rule)) {
                // Generate a unique file identifier using functions
                $saveName = $rule().".".$filename['extension'];
            }else {
                // Use the given file name as the identification number
                $saveName = $rule.".".$filename['extension'];
            }
        }
        if($this->autoSub) {
            // Use subdirectories to save files
            $filename['savename'] = $saveName;
            $saveName = $this->getSubName($filename).$saveName;
        }
        return $saveName;
    }

    /**
     * Get the name of the subdirectory
     * @access private
     *@ File information uploaded by param array $file
     * @return string
     */
    private function getSubName($file) {
        switch($this->subType) {
            case 'custom':
                $dir    =   $this->subDir;
                break;
            case 'date':
                $dir    =   date($this->dateFormat,time()).'/';
                break;
            case 'hash':
            default:
                $name   =   md5($file['savename']);
                $dir    =   '';
                for($i=0;$i<$this->hashLevel;$i++) {
                    $dir   .=  $name{$i}.'/';
                }
                break;
        }
        if(!is_dir($file['savepath'].$dir)) {
            mkdir($file['savepath'].$dir,0777,true);
        }
        return $dir;
    }

    /**
     * Check uploaded files
     * @access private
     *@ Param array $file file file information
     * @return boolean
     */
    private function check($file) {
        if($file['error']!== 0) {
            // File upload failed
            // Capture error code
            $this->error($file['error']);
            return false;
        }
        // File upload was successful and custom rule checking was performed
        // Check file size
        if(!$this->checkSize($file['size'])) {
            $this - > error = upload file size does not match! ';
            return false;
        }

        // Check file Mime type
        if(!$this->checkType($file['type'])) {
            This - > error = upload file MIME type is not allowed! ';
            return false;
        }
        // Check file type
        if(!$this->checkExt($file['extension'])) {
            $this - > error ='upload file type is not allowed';
            return false;
        }

        // Check for legal upload
        if(!$this->checkUpload($file['tmp_name'])) {
            $this - > error = illegal upload of files! ';
            return false;
        }
        return true;
    }

    // Automatic Conversion Character Set Support Array Conversion
    private function autoCharset($fContents, $from='gbk', $to='utf-8') {
        $from   = strtoupper($from) == 'UTF8' ? 'utf-8' : $from;
        $to     = strtoupper($to) == 'UTF8' ? 'utf-8' : $to;
        if (strtoupper($from) === strtoupper($to) || empty($fContents) || (is_scalar($fContents) && !is_string($fContents))) {
            // If the encoding is the same or if the non-string scalar is not converted
            return $fContents;
        }
        if (function_exists('mb_convert_encoding')) {
            return mb_convert_encoding($fContents, $to, $from);
        } elseif (function_exists('iconv')) {
            return iconv($from, $to, $fContents);
        } else {
            return $fContents;
        }
    }

    /**
     * Check uploaded files类型是否合法
     * @access private
     *@ Param string $type data
     * @return boolean
     */
    private function checkType($type) {
        if(!empty($this->allowTypes))
            return in_array(strtolower($type),$this->allowTypes);
        return true;
    }


    /**
     * Check uploaded files后缀是否合法
     * @access private
     *@ Param string $ext suffix name
     * @return boolean
     */
    private function checkExt($ext) {
        if(!empty($this->allowExts))
            return in_array(strtolower($ext),$this->allowExts,true);
        return true;
    }

    /**
     * Check file size for legitimacy
     * @access private
     *@ Param integer $size data
     * @return boolean
     */
    private function checkSize($size) {
        return !($size > $this->maxSize) || (-1 == $this->maxSize);
    }

    /**
     * Check for illegal submission of documents
     * @access private
     *@ Param string $filename file name
     * @return boolean
     */
    private function checkUpload($filename) {
        return is_uploaded_file($filename);
    }

    /**
     * Get the suffix of the uploaded file
     * @access private
     *@ Param string $filename file name
     * @return boolean
     */
    private function getExt($filename) {
        $pathinfo = pathinfo($filename);
        return $pathinfo['extension'];
    }

    /**
     * Get information about uploaded files
     * @access public
     * @return array
     */
    public function getUploadFileInfo() {
        return $this->uploadFileInfo;
    }

    /**
     * Get the last error message
     * @access public
     * @return string
     */
    public function getErrorMsg() {
        return $this->error;
    }
}

4.2 испытание

4.2.1 Установка композитора выполнения терминала Это создает каталоги поставщиков и другие документы

[email protected] MINGW64 /i/phpstudy/WWW/uploadfile
$ composer install

4.2.2 NEWuploadfile/test/UpploadFileTest.php、uploadfile/test/UpploadFile.html

  • 4.2.2 NEWuploadfile/test/UpploadFileTest.php、uploadfile/test/UpploadFile.html
 maxSize = 1 * 1024 * 1024; // Default is - 1, no limit on upload size
$upload - > savePath ='. / upload /'; // upload the root directory
$upload - > saveRule ='uniqid'; // File name saving rules for uploaded files
$upload - > uploadReplace = true; // If a file with the same name exists, whether it is overwritten or not
$upload - > autoSub = true; // upload subdirectory open
$upload - > subType ='date'; // Upload subdirectory naming rules
$upload - > allowExts = ['jpg','png']; // allowed type

if ($upload->upload()) {
    var_dump($upload->getUploadFileInfo());
} else {
    var_dump($upload->getErrorMsg());
}
  • 4.2.2 NEWuploadfile/test/UpploadFileTest.php、uploadfile/test/UpploadFile.html




    
    uploadfile test
    


    
< label > single file upload

< label > multi-file upload

4.2.3 Доступ к Локальному браузеру uploadfile/test/UpploadFile.html Тестирование

Пять, добавьте README.md、ЛИЦЕНЗИЯ、.gitignore Окончательная структура проекта выглядит следующим образом: Адрес моего пакета на GitHub

-uploadfile Extended Package Root Directory
-src Extension Package Code Directory
│  │  ├─UploadFile.php
-test test test catalogue
│  │  ├─uploadfile.html
│  │  ├─UpploadfileTest.php
│  ├─.gitignore
│  ├─composer.json
│  ├─LICENSE
│  └─README.md

6. Переход на GitHub

git add .
git commit -m 'init'
Git tag v1.0.0//Remember to type a version number
git push origin master
git push v1.0.0

7. Отправляйте пакеты на GitHub упаковщику

  1. Во-первых, зарегистрируйте свою учетную запись на Packagist и войдите в систему (вы можете войти непосредственно на GitHub).
  2. Нажмите кнопку Отправить в верхней панели навигации
  3. В поле ввода введите адрес предыдущего пакета на GitHub, например: https://github.com/guanguans/uploadfile
  4. Затем нажмите на кнопку Проверить упаковщика, чтобы проверить, соответствует ли код адреса склада требованиям пакета Composer.

Если обнаружение в норме, появится кнопка Отправить, затем нажмите кнопку Отправить, и наш пакет будет отправлен упаковщику.

8. Настройка пакета composer для автоматического обновления

Когда мы обновляем репозиторий GitHub, пакет в Packagist автоматически не обновляется. Теперь давайте настроим автоматическое обновление.

8.1 Копирование маркера API профиля

8.2 Откройте настройки проекта на GitHub, выберите “Интеграция и службы”, Добавьте службу упаковщика, нажмите “Служба тестирования”.

8.3 Убедитесь, что были сделаны автоматические обновления

Просмотрите домашнюю страницу пакета Packagist и обнаружите, что там нет красной подсказки о блокировке, указывающей на то, что настройки автоматически успешно обновлены.

IX. Использование в проектах

Я использую Laravel в качестве примера

composer create-project laravel/laravel
cd laravel
composer require guanguans/uploadfile

Другой

  • Этот общий класс загрузки изменяется с помощью файла загрузки. класс. PHP в ThinkPHP
  • Первая статья Блог Читайте больше статей.

Эта статья В китайском стиле Оригинальные статьи, перепечатанные без контакта со мной, но, пожалуйста, укажите из Блог Гуань гуань https://guanguanguans.cn