乐趣区

关于php:php代码片段-sendFilevideoStreamsendEmailphpexcelffmpegzip

sendFile 发送文件

<?php
$doc = filter_input(INPUT_GET, 'file');

if ($doc) {
    // decode requested file path
    $docPath = base64_decode($doc);

    // check file path
    if ($docPath !== false && file_exists($docPath)) {$mimeType = Utils::get_mime_type($docPath);
        
        if (stripos($mimeType, 'audio/') !== false || stripos($mimeType, 'video/') !== false) {
            // streaming media
            $stream = new VideoStream($docPath);
            $stream->start();} else {
            // output document
            $fName = basename(filter_input(INPUT_SERVER, 'PATH_INFO'));
            $fSize = filesize($docPath);

            if (strpos($fName, '.') === false && strrpos(basename($docPath), '.') !== false) {$ext = substr(basename($docPath), -strrpos(basename($docPath), '.'));
                $fName .= $ext;
            }

            header('Content-type:' . $mimeType);
            header('Content-disposition: filename="' . $fName . '"');
            header('Content-Length:' . $fSize);

            flush();
            $fHandle = fopen($docPath, 'r');
            while (!feof($fHandle)) {
                // send the current file part to the browser
                print fread($fHandle, 8192);
                // flush the content to the browser
                flush();}
            fclose($fHandle);
        }

    } else {header('HTTP/1.0 401 Unauthorized');
        echo 'Unauthorized access';

        // log
        $fh = @fopen('getDoc.log', 'a');
        if ($fh !== false) {
            $msg = 'Try to access not existing file';
            fwrite($fh, PHP_EOL . date('Y-m-d H:i:s') . '***' . $msg . ' ' . $docPath);
            fclose($fh);
        }
    }
}

videoStream 发送视频流

<?php
class VideoStream {
    private $path = '';
    private $stream = null;
    private $buffer = 102400;
    private $start = -1;
    private $end = -1;
    private $size = 0;

    /**
     * @param string $filePath
     */
    public function setPath($filePath) {$this->path = $filePath;}

    /**
     * Open stream
     */
    private function open() {if (!($this->stream = fopen($this->path, 'rb'))) {die('Could not open stream for reading');
        }
    }

    /**
     * Set proper header to serve the video content
     */
    private function setHeader() {ob_get_clean();
        $mimeType = \Utils::get_mime_type($this->path);
        header("Content-Type:" . $mimeType);
        header("Cache-Control: max-age=2592000, public");
        header("Expires:" . gmdate('D, d M Y H:i:s', time() + 2592000) . 'GMT');
        header("Last-Modified:" . gmdate('D, d M Y H:i:s', @filemtime($this->path)) . 'GMT');
        $this->start = 0;
        $this->size = filesize($this->path);
        $this->end = $this->size - 1;
        header("Accept-Ranges: 0-" . $this->end);

        if (isset($_SERVER['HTTP_RANGE'])) {
            $c_end = $this->end;

            list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
            if (strpos($range, ',') !== false) {header('HTTP/1.1 416 Requested Range Not Satisfiable');
                header("Content-Range: bytes $this->start-$this->end/$this->size");
                exit;
            }
            if ($range == '-') {$c_start = $this->size - substr($range, 1);
            } else {$range = explode('-', $range);
                $c_start = $range[0];

                $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end;
            }
            $c_end = ($c_end > $this->end) ? $this->end : $c_end;
            if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) {header('HTTP/1.1 416 Requested Range Not Satisfiable');
                header("Content-Range: bytes $this->start-$this->end/$this->size");
                exit;
            }
            $this->start = $c_start;
            $this->end = $c_end;
            $length = $this->end - $this->start + 1;
            fseek($this->stream, $this->start);
            header('HTTP/1.1 206 Partial Content');
            header("Content-Length:" . $length);
            header("Content-Range: bytes $this->start-$this->end/" . $this->size);
        } else {header("Content-Length:" . $this->size);
        }

    }

    /**
     * close currently opened stream
     */
    private function end() {fclose($this->stream);
        exit;
    }

    /**
     * perform the streaming of calculated range
     */
    private function stream() {
        $i = $this->start;
        set_time_limit(0);
        while (!feof($this->stream) && $i <= $this->end) {
            $bytesToRead = $this->buffer;
            if (($i + $bytesToRead) > $this->end) {$bytesToRead = $this->end - $i + 1;}
            $data = fread($this->stream, $bytesToRead);
            echo $data;
            flush();
            $i += $bytesToRead;
        }
    }

    /**
     * Start streaming video content
     */
    public function start() {$this->open();
        $this->setHeader();
        $this->stream();
        $this->end();}
}

sendEmail 发送邮件

<?php
$transport = new \Zend\Mail\Transport\Sendmail();
$attachment = array();

// add properties
$msg = new \Zend\Mail\Message();
$msg->addFrom('fromEmail', 'fromName')
    ->addTo('toEmail')
    ->setSubject('subject')
    ->addCc('ccEmail')
    ->addBcc('bccEmail');

if (count($attachment) > 0) {
    // new MIME message
    $mimeMessage = new \Zend\Mime\Message();

    // add body
    $text = new \Zend\Mime\Part(nl2br('body'));
    $text->type = \Zend\Mime\Mime::TYPE_HTML;
    $text->charset = 'utf-8';
    $mimeMessage->addPart($text);

    // add attachment
    foreach ($attachment as $fPath) {if (file_exists($fPath)) {$attachment = new \Zend\Mime\Part(fopen($fPath, 'r'));
            $attachment->type = \Zend\Mime\Mime::TYPE_OCTETSTREAM;
            $attachment->filename = basename($fPath);
            $attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
            $attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
            $mimeMessage->addPart($attachment);
        }
    }
    $msg->setBody($mimeMessage);
} else {$msg->setBody('body');
}

$transport->send($msg);

phpexcel 电子表格解决

<?php
class Exporter {
    /** @var string */
    public $filename;

    /** @var string */
    public $creator;

    /** @var string */
    public $title;

    /** @var string */
    public $description;

    /** @var string */
    public $subject;

    /** @var string */
    public $keywords;

    /** @var boolean */
    public $boldTitle;

    /** @var boolean */
    public $autoSizeText;

    /**
     * @var array
     * array(<sheet_index> => array('selector' => <cell_selector>,'style' => <PHPExcel_style_array>))
     */
    public $cellStyles;

    public function __construct() {$this->filename = date('Y_m_d_H_i_s', time()) . '.xlsx';
        $this->creator = '';
        $this->title = '';
        $this->description = '';
        $this->subject = '';
        $this->keywords = '';
        $this->boldTitle = false;
        $this->autoSizeText = false;
        $this->cellStyles = array();}

    /**
     * @param string
     */
    public function setFilename($fullFilename) {$this->filename = $fullFilename;}

    /**
     * @param string
     */
    public function setCreator($creator) {$this->creator = $creator;}

    /**
     * @param string
     */
    public function setTitle($title) {$this->title = $title;}

    /**
     * @param string
     */
    public function setDescription($description) {$this->description = $description;}

    /**
     * @param string
     */
    public function setSubject($subject) {$this->subject = $subject;}

    /**
     * @param string
     */
    public function setKeywords($keywords) {$this->keywords = $keywords;}

    /**
     * @param boolean
     */
    public function setBoldTitle($boldTitle) {$this->boldTitle = $boldTitle;}

    /**
     * @param boolean
     */
    public function setAutoSizeText($autoSizeText) {$this->autoSizeText = $autoSizeText;}

    /**
     * @param array
     */
    public function setCellStyles($cellStyles) {$this->cellStyles = $cellStyles;}

    /**
     *
     * @param array $sheetItems
     * @return string filename
     */
    public function export($sheetItems) {
        //Generate PHPExcel
        $excel = new \PHPExcel();
        $excel->getProperties()
            ->setCreator($this->creator)
            ->setTitle($this->title)
            ->setDescription($this->description)
            ->setSubject($this->subject)
            ->setKeywords($this->keywords);

        $idxSheet = 0;
        $lastColumn = null;
        foreach ($sheetItems as $sheetName => $items) {if ($idxSheet > 0) {$excel->createSheet($idxSheet);
            }
            $currSheet = $excel->setActiveSheetIndex($idxSheet);
            $currSheet->setTitle(mb_substr($sheetName, 0, 31));

            //Fill data
            $idxRow = 1;
            foreach ($items as $subDatas) {
                $idxCol = 0;
                foreach ($subDatas as $itemValue) {$coords = \PHPExcel_Cell::stringFromColumnIndex($idxCol) . $idxRow;
                    $currSheet->setCellValueExplicit($coords, $itemValue, \PHPExcel_Cell_DataType::TYPE_STRING);
                    $idxCol++;
                }
                $idxRow++;
            }

            //Style: title bold
            if ($this->boldTitle) {$lastColumn = $currSheet->getHighestColumn();
                $currSheet->getStyle('A1:' . $lastColumn . '1')->applyFromArray(array('font' => array('bold' => true)));
            }

            //Style: wrap and autosize text
            if ($this->autoSizeText) {$lastColumn = ($lastColumn) ? : $currSheet->getHighestColumn();
                $currSheet->getStyle('A2:' . $lastColumn . $idxRow)->getAlignment()->setWrapText(true);
                $iterator = $lastColumn;
                $iterator++;
                for ($column = 'A'; $column != $iterator; $column++) {$currSheet->getColumnDimension($column)->setAutoSize(true);
                }
            }

            //Style cells
            if (count($this->cellStyles) > 0 && isset($this->cellStyles[$idxSheet])) {foreach ($this->cellStyles[$idxSheet] as $row) {$currSheet->getStyle($row['selector'])->applyFromArray($row['style']);
                }
            }

            $currSheet->garbageCollect();
            $idxSheet++;
        }

        //Save
        $excel->setActiveSheetIndex(0);
        $writer = \PHPExcel_IOFactory::createWriter($excel, 'Excel2007');
        $writer->save($this->filename);
        return $this->filename;
    }
}

ffmpeg 图片批改

<?php
/**
 * exp: Convert video to mp4
 * $ffmpeg = new FFMpeg();
 * $ffmpeg->open('xxx');
 * $ffmpeg->setVcodec('libx264');
 * $ffmpeg->setVquality('28');
 * $ffmpeg->setAcodec('aac');
 * $ffmpeg->setAquality('128k');
 * $ffmpeg->setDuration('30');
 * $success = $ffmpeg->save('xxx.mp4');
 */

/**
 * exp: Convert audio to mp3
 * $ffmpeg = new FFMpeg();
 * $ffmpeg->setAcodec('libmp3lame');
 * $ffmpeg->setAquality('6');
 * $ffmpeg->setDuration('30');
 * $success = $ffmpeg->save('xxx.mp3');
 */

/**
 * exp: Export screenshot
 * $ffmpeg = new FFMpeg();
 * $ffmpeg->open('xxx.mp4');
 * $ffmpeg->setPosition('10');
 * $ffmpeg->exportScreenshot('test.png');
 */

/**
 * exp: avconv -i  source_path -codec:v libx264 -crf 28 -codec:a aac -b:a 128k -strict experimental dest_path
 */

/**
 * Class FFMpeg
 */
class FFMpeg
{
    /**
     * @var bool
     * Overwrite output files without asking.
     */
    private $overwrite = true;

    /**
     * @var string
     * file path of (input)
     */
    private $path = '';

    /**
     * @var string
     * video codec (output)
     */
    private $vcodec = '';

    /**
     * @var string
     * audio codec (output)
     */
    private $acodec = '';

    /**
     * @var string
     * duration (output)
     *
     * Stop writing the output after its duration reaches duration.
     * duration may be a number in seconds, or in hh:mm:ss[.xxx] form.
     */
    private $duration = '';

    /**
     * @var string
     * quality (output audio)
     * FOR libmp3lame: 0-9 (a lower value is a higher quality
     * 0-3 will normally produce transparent results,
     * 4 (default) should be close to perceptual transparency,
     * 6 produces an "acceptable" quality.)
     * FOR OTHERS: bitrate (in bits/s) 128k, 256k
     */
    private $aquality = '';

    /**
     * @var string
     * quality (output video)
     * FOR libx264: 0-51 (0: lossless, 23: default, 51: rubbish,
     * A value of 18-28 is considered "sane" with 18 being "visually lossless".)
     * FOR OTHERS: bitrate (in bits/s) 800k, 1000k
     */
    private $vquality = '';

    /**
     * @var string
     * position may be either in seconds or in hh:mm:ss[.xxx] form. (input video)
     */
    private $position = '3';

    /**
     * @var string
     * This will scale to your desired width
     * and the height will be automatically scaled to the appropriate value to preserve aspect.
     */
    private $width = '';

    /**
     * @param string $filePath
     */
    public function __construct($filePath = '')
    {$this->path = $filePath;}

    /**
     * @param boolean $overwrite
     */
    public function setOverwrite($overwrite)
    {$this->overwrite = $overwrite;}

    /**
     * @param string $aquality
     */
    public function setAquality($aquality)
    {$this->aquality = $aquality;}

    /**
     * @param string $vquality
     */
    public function setVquality($vquality)
    {$this->vquality = $vquality;}

    /**
     * @param string $duration
     */
    public function setDuration($duration)
    {$this->duration = $duration;}

    /**
     * @param string $filePath
     */
    public function open($filePath)
    {$this->path = $filePath;}

    /**
     * @param string $acodec
     */
    public function setAcodec($acodec)
    {$this->acodec = $acodec;}

    /**
     * @param string $vcodec
     */
    public function setVcodec($vcodec)
    {$this->vcodec = $vcodec;}

    /**
     * @param string $position
     */
    public function setPosition($position)
    {$this->position = $position;}

    /**
     * @param string $width
     */
    public function setWidth($width)
    {$this->width = $width;}

    /**
     * @param string $filename
     * @return bool
     * @throws \Exception
     */
    public function save($filename)
    {if (!file_exists($this->path)) {return false;}

        //Do ffmpeg command
        $cmdLine = 'avconv -i' . str_replace('','\ ', $this->path);
        if ($this->overwrite) {$cmdLine .= '-y';}

        // video codec
        if ($this->vcodec !== '') {$cmdLine .= '-codec:v' . $this->vcodec;}

        // video quality
        if ($this->vcodec !== ''&& $this->vquality !=='') {if (stripos($this->vcodec, 'libx264') !== false || stripos($this->vcodec, 'h264') !== false) {if ($this->vquality >= 0 && $this->vquality <= 51) {$cmdLine .= '-crf' . $this->vquality; //h264 use -crf} else {throw new \Exception('quality of video: invalid argument (0-51)');
                }
            } else {if (stripos($this->vquality, 'k') !== false) {$cmdLine .= '-b:v' . $this->vquality; // others can user -b:v (bitrate)
                } else {throw new \Exception('quality of video: invalid argument (128k, 256k...)');
                }
            }
        }

        // audio codec
        if ($this->acodec !== '') {$cmdLine .= '-codec:a' . $this->acodec;}

        // audio quality
        if ($this->acodec !== ''&& $this->aquality !=='') {if (stripos($this->acodec, 'libmp3lame') !== false || stripos($this->acodec, 'mp3') !== false) {if ($this->aquality >= 0 && $this->aquality <= 9) {$cmdLine .= '-q:a' . $this->aquality; //mp3 use -qscale:a} else {throw new \Exception('quality of audio: invalid argument (0-9)');
                }
            } else {if (stripos($this->aquality, 'k') !== false) {$cmdLine .= '-b:a' . $this->aquality; // others can user -b:a (bitrate)
                } else {throw new \Exception('quality of audio: invalid argument (128k, 256k...)');
                }
            }
        }

        // ouput maximium duration
        if ($this->duration !== '') {$cmdLine .= '-t' . $this->duration;}
        // strict mode
        $cmdLine .= '-strict experimental' . str_replace('','\ ', $filename);

        $exec = shell_exec($cmdLine);
        return ($exec === null);
    }

    /**
     * @param string $imagename
     * @return bool
     */
    public function exportScreenshot($imagename)
    {if (!file_exists($this->path)) {return false;}

        //Do ffmpeg command
        $cmdLine = 'avconv -i' . str_replace('','\ ', $this->path);
        if ($this->overwrite) {$cmdLine .= '-y';}
        if ($this->position) {$cmdLine .= '-ss' . $this->position;}
        if ($this->width) {$cmdLine .= '-filter:v scale=' . $this->width . ':-1';}
        $cmdLine .= '-frames:v 1' . str_replace('','\ ', $imagename);

        $exec = shell_exec($cmdLine);
        return ($exec === null);
    }
}

zip 压缩包

<?php

class Zip
{

    /** @var string */
    protected $_encoding;

    /** @var string */
    public $filename;

    /**
     * Zip constructor.
     */
    public function __construct()
    {$this->setEncoding('CP437//IGNORE//TRANSLIT');
        $this->filename = time() . '.zip';}

    /**
     * @param string $enc
     */
    public function setEncoding($enc = null)
    {$this->_encoding = $enc;}

    /**
     * @param string $fullFilename
     */
    public function setFilename($fullFilename)
    {$this->filename = $fullFilename;}

    /**
     *
     * @param array $paths string[]
     * @return boolean TRUE on success, FALSE on failure
     */
    public function compress($paths)
    {if (!is_array($paths)) {return false;}

        // TODO: rename file
        $cleanPaths = array();
        foreach ($paths as $path) {$bName = basename($path);
            if ($this->_encoding !== null) {$bName = iconv('UTF-8', $this->_encoding, $bName);
            }
            $cleanPaths[$path] = $bName;
        }

        if (shell_exec('which zip') !== null) {$success = $this->_compressShell($cleanPaths);
        } else {$success = $this->_compressZipArchive($cleanPaths);
        }

        return $success;
    }

    /**
     * @param array $cleanPaths Files to archive.
     * key: full file path, value: new file name
     * @return boolean TRUE on success or FALSE on failure.
     */
    protected function _compressShell($cleanPaths)
    {
        // create temporary working folder
        $tmpDir = basename($this->filename, '_tmpDir') . '/';
        if (is_dir($tmpDir)) {if (!$this->_deleteDir($tmpDir)) {return false;}
        }

        if (!mkdir($tmpDir, 0777, true)) {return false;}

        // copy files to temporary working folder
        foreach ($cleanPaths as $path => $cleanPath) {copy($path, $tmpDir . $cleanPath);
        }

        // zip, 1->compress faster, j->junk (don't record) directory names, q->quiet operation
        $cmd = 'zip -1jq' . $this->filename . '' . $tmpDir .'*';
        $output = array();
        exec($cmd, $output, $return);

        // delete temporary working folder
        $this->_deleteDir($tmpDir);

        // return will return non-zero upon an error
        if (!$return) {return true;} else {return false;}
    }

    /**
     * @param array $cleanPaths Files to archive.
     * key: full file path, value: new file name
     * @return boolean TRUE on success or FALSE on failure.
     */
    protected function _compressZipArchive($cleanPaths)
    {$zip = new \ZipArchive();

        // open zip file
        $zip->open($this->filename, \ZipArchive::CREATE);

        // add files,
        // TODO: improve performance
        foreach ($cleanPaths as $path => $cleanPath) {$zip->addFile($path, $cleanPath);
        }

        // close zip
        return $zip->close();}

    /**
     * @param $dirPath
     * @return boolean
     */
    protected function _deleteDir($dirPath)
    {if (!is_dir($dirPath)) {return false;}

        if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {$dirPath .= '/';}

        foreach (glob($dirPath . '*', GLOB_MARK) as $file) {if (is_dir($file)) {$this->_deleteDir($file);
            } else {unlink($file);
            }
        }
        return rmdir($dirPath);
    }

    /**
     * @param string $destination
     * @param array $entries
     * @return boolean
     */
    public function deCompress($destination, $entries = null)
    {$zip = new \ZipArchive();
        $zip->open($this->filename, \ZipArchive::CREATE);
        $res = $zip->extractTo($destination, $entries = null);
        $zip->close();
        return $res;
    }

}

utils 工具函数

<?php
/**
 * Get memory usage
 * @return string
 */
public static
function get_memory_usage() {$mem_usage = memory_get_peak_usage(true);
    if ($mem_usage < 1024) {return $mem_usage . "bytes";}
    elseif($mem_usage < 1048576) {return round($mem_usage / 1024, 2) . "KB";
    } else {return round($mem_usage / 1048576, 2) . "MB";
    }
}

/**
 * Detemine is JSON and decode JSON
 * @param string $json
 * @param bool $return_data
 * @return mixed the formed array or true on success, or false on failure
 */
public static function is_json($json, $return_data = false) {$data = json_decode($json, true);
    return (json_last_error() == JSON_ERROR_NONE) ? ($return_data ? $data : TRUE) : FALSE;
}

/**
 * Set ini memory limit
 * @param mixed $newV string '1024M' or int 1024
 * @return string the old value on success, false on failure.
 */
public static function ini_set_memory_limit($newV) {$newVInt = (int)str_ireplace('M', '', (string)$newV);
    $oldV = ini_get('memory_limit');
    $oldVInt = (int)str_ireplace('M', '', (string)$oldV);

    if ($oldVInt < $newVInt) {return ini_set('memory_limit', $newVInt . 'M');
    }
    return $oldV;
}

/**
 * Get mine type of file
 * @param string $filename
 * @return mixed the mine type on success, or false on failure
 */
public static function get_mime_type($filename) {$realpath = realpath($filename);
    if($realpath) {if (function_exists('finfo_file') && function_exists('finfo_open') && defined('FILEINFO_MIME_TYPE')) {$finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mimetype = finfo_file($finfo, $realpath);
            finfo_close($finfo);
            return $mimetype;
        }
        if (function_exists('mime_content_type')) {return mime_content_type($realpath);
        }
    }
    return false;
}
退出移动版