PHP数据库基于PDO操作类(mysql)

这是网上找的关于Mysql的操作类,非常适合初学者使用

<?php

class Mysql {

        protected static $_dbh = null; //静态属性,所有数据库实例共用,避免重复连接数据库
        protected $_dbType = 'mysql';
        protected $_pconnect = true; //是否使用长连接
        protected $_host = 'localhost';
        protected $_port = 3306;
        protected $_user = 'root';
        protected $_pass = '';
        protected $_dbName = null; //数据库名
        protected $_sql = false; //最后一条sql语句
        protected $_where = '';
        protected $_order = '';
        protected $_limit = '';
        protected $_field = '*';
        protected $_clear = 0; //状态,0表示查询条件干净,1表示查询条件污染
        protected $_trans = 0; //事务指令数 

        /**
         * 初始化类
         * @param array $conf 数据库配置
         */
        public function __construct(array $conf) {
            class_exists('PDO') or die("PDO: class not exists.");
            $this->_host = $conf['host'];
            $this->_port = $conf['port'];
            $this->_user = $conf['user'];
            $this->_pass = $conf['password'];
            $this->_dbName = $conf['dbname'];
            //连接数据库
            if ( is_null(self::$_dbh) ) {
                $this->_connect();
            }
        }

        /**
         * 连接数据库的方法
         */
        protected function _connect() {
            $dsn = $this->_dbType.':host='.$this->_host.';port='.$this->_port.';dbname='.$this->_dbName;
            //持久化连接
            $options = $this->_pconnect ? array(PDO::ATTR_PERSISTENT=>true) : array();
            try { 
                $dbh = new PDO($dsn, $this->_user, $this->_pass, $options);
                $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  //设置如果sql语句执行错误则抛出异常,事务会自动回滚
                $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //禁用prepared statements的仿真效果(防SQL注入)
            } catch (PDOException $e) { 
                die('Connection failed: ' . $e->getMessage());
            }
            $dbh->exec('SET NAMES utf8');
            self::$_dbh = $dbh;
        }

        /** 
        * 字段和表名添加 `符号
        * 保证指令中使用关键字不出错 针对mysql 
        * @param string $value 
        * @return string 
        */
        protected function _addChar($value) { 
            if ('*'==$value || false!==strpos($value,'(') || false!==strpos($value,'.') || false!==strpos($value,'`')) { 
                //如果包含* 或者 使用了sql方法 则不作处理 
            } elseif (false === strpos($value,'`') ) { 
                $value = '`'.trim($value).'`';
            } 
            return $value; 
        }

        /** 
        * 取得数据表的字段信息 
        * @param string $tbName 表名
        * @return array 
        */
        protected function _tbFields($tbName) {
            $sql = 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="'.$tbName.'" AND TABLE_SCHEMA="'.$this->_dbName.'"';
            $stmt = self::$_dbh->prepare($sql);
            $stmt->execute();
            $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
            $ret = array();
            foreach ($result as $key=>$value) {
                $ret[$value['COLUMN_NAME']] = 1;
            }
            return $ret;
        }

        /** 
        * 过滤并格式化数据表字段
        * @param string $tbName 数据表名 
        * @param array $data POST提交数据 
        * @return array $newdata 
        */
        protected function _dataFormat($tbName,$data) {
            if (!is_array($data)) return array();
            $table_column = $this->_tbFields($tbName);
            $ret=array();
            foreach ($data as $key=>$val) {
                if (!is_scalar($val)) continue; //值不是标量则跳过
                if (array_key_exists($key,$table_column)) {
                    $key = $this->_addChar($key);
                    if (is_int($val)) { 
                        $val = intval($val); 
                    } elseif (is_float($val)) { 
                        $val = floatval($val); 
                    } elseif (preg_match('/^\(\w*(\+|\-|\*|\/)?\w*\)$/i', $val)) {
                        // 支持在字段的值里面直接使用其它字段 ,例如 (score+1) (name) 必须包含括号
                        $val = $val;
                    } elseif (is_string($val)) { 
                        //将字符串中的单引号(')、双引号(")、反斜线(\)与 NUL(NULL 字符转义
                        $val = '"'.addslashes($val).'"';
                    }
                    $ret[$key] = $val;
                }
            }
            return $ret;
        }

        /**
        * 执行查询 主要针对 SELECT, SHOW 等指令
        * @param string $sql sql指令 
        * @return mixed 
        */
        protected function _doQuery($sql='') {
            $this->_sql = $sql;
            $pdostmt = self::$_dbh->prepare($this->_sql); //prepare或者query 返回一个PDOStatement
            $pdostmt->execute();
            $result = $pdostmt->fetchAll(PDO::FETCH_ASSOC);
            return $result;
        }

        /** 
        * 执行语句 针对 INSERT, UPDATE 以及DELETE,exec结果返回受影响的行数
        * @param string $sql sql指令 
        * @return integer 
        */
        protected function _doExec($sql='') {
            $this->_sql = $sql;
            return self::$_dbh->exec($this->_sql);
        }

        /** 
        * 执行sql语句,自动判断进行查询或者执行操作 
        * @param string $sql SQL指令 
        * @return mixed 
        */
        public function doSql($sql='') {
            $queryIps = 'INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|SELECT .* INTO|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK'; 
            if (preg_match('/^\s*"?(' . $queryIps . ')\s+/i', $sql)) { 
                return $this->_doExec($sql);
            }
            else {
                //查询操作
                return $this->_doQuery($sql);
            }
        }

        /** 
        * 获取最近一次查询的sql语句 
        * @return String 执行的SQL 
        */
        public function getLastSql() { 
            return $this->_sql;
        }

        /**
         * 插入方法
         * @param string $tbName 操作的数据表名
         * @param array $data 字段-值的一维数组
         * @return int 受影响的行数
         */
        public function insert($tbName,array $data){
            $data = $this->_dataFormat($tbName,$data);
            if (!$data) return;
            $sql = "insert into ".$tbName."(".implode(',',array_keys($data)).") values(".implode(',',array_values($data)).")";
            return $this->_doExec($sql);
        }

        /**
         * 删除方法
         * @param string $tbName 操作的数据表名
         * @return int 受影响的行数
         */
        public function delete($tbName) {
            //安全考虑,阻止全表删除
            if (!trim($this->_where)) return false;
            $sql = "delete from ".$tbName." ".$this->_where;
            $this->_clear = 1;
            $this->_clear();
            return $this->_doExec($sql);
        }

        /**
         * 更新函数
         * @param string $tbName 操作的数据表名
         * @param array $data 参数数组
         * @return int 受影响的行数
         */
        public function update($tbName,array $data) {
            //安全考虑,阻止全表更新
            if (!trim($this->_where)) return false;
            $data = $this->_dataFormat($tbName,$data);
            if (!$data) return;
            $valArr = '';
            foreach($data as $k=>$v){
                $valArr[] = $k.'='.$v;
            }
            $valStr = implode(',', $valArr);
            $sql = "update ".trim($tbName)." set ".trim($valStr)." ".trim($this->_where);
            return $this->_doExec($sql);
        }

        /**
         * 查询函数
         * @param string $tbName 操作的数据表名
         * @return array 结果集
         */
        public function select($tbName='') {
            $sql = "select ".trim($this->_field)." from ".$tbName." ".trim($this->_where)." ".trim($this->_order)." ".trim($this->_limit);
            //echo $sql;
            $this->_clear = 1;
            $this->_clear();
            return $this->_doQuery(trim($sql));
        }

        /**
         * @param mixed $option 组合条件的二维数组,例:$option['field1'] = array(1,'=>','or')
         * @return $this
         */
        public function where($option) {
            if ($this->_clear>0) $this->_clear();
            $this->_where = ' where ';
            $logic = 'and';
            if (is_string($option)) {
                $this->_where .= $option;
            }
            elseif (is_array($option)) {
                foreach($option as $k=>$v) {
                    if (is_array($v)) {
                        $relative = isset($v[1]) ? $v[1] : '=';
                        $logic    = isset($v[2]) ? $v[2] : 'and';
                        $condition = ' ('.$this->_addChar($k).' '.$relative.' '.$v[0].') ';
                    }
                    else {
                        $logic = 'and';
                        $condition = ' ('.$this->_addChar($k).'='.$v.') ';
                    }
                    $this->_where .= isset($mark) ? $logic.$condition : $condition;
                    $mark = 1;
                }
            }
            return $this;
        }

        /**
         * 设置排序
         * @param mixed $option 排序条件数组 例:array('sort'=>'desc')
         * @return $this
         */
        public function order($option) {
            if ($this->_clear>0) $this->_clear();
            $this->_order = ' order by ';
            if (is_string($option)) {
                $this->_order .= $option;
            }
            elseif (is_array($option)) {
                foreach($option as $k=>$v){
                    $order = $this->_addChar($k).' '.$v;
                    $this->_order .= isset($mark) ? ','.$order : $order;
                    $mark = 1;
                }
            }
            return $this;
        }

        /**
         * 设置查询行数及页数
         * @param int $page pageSize不为空时为页数,否则为行数
         * @param int $pageSize 为空则函数设定取出行数,不为空则设定取出行数及页数
         * @return $this
         */
        public function limit($page,$pageSize=null) {
            if ($this->_clear>0) $this->_clear();
            if ($pageSize===null) {
                $this->_limit = "limit ".$page;
            }
            else {
                $pageval = intval( ($page - 1) * $pageSize);
                $this->_limit = "limit ".$pageval.",".$pageSize;
            }
            return $this;
        }

        /**
         * 设置查询字段
         * @param mixed $field 字段数组
         * @return $this
         */
        public function field($field){
            if ($this->_clear>0) $this->_clear();
            if (is_string($field)) {
                $field = explode(',', $field);
            }
            $nField = array_map(array($this,'_addChar'), $field);
            $this->_field = implode(',', $nField);
            return $this;
        }

        /**
         * 清理标记函数
         */
        protected function _clear() {
            $this->_where = '';
            $this->_order = '';
            $this->_limit = '';
            $this->_field = '*';
            $this->_clear = 0;
        }

        /**
         * 手动清理标记
         * @return $this
         */
        public function clearKey() {
            $this->_clear();
            return $this;
        }

        /**
        * 启动事务 
        * @return void 
        */
        public function startTrans() { 
            //数据rollback 支持 
            if ($this->_trans==0) self::$_dbh->beginTransaction();
            $this->_trans++; 
            return; 
        }

        /** 
        * 用于非自动提交状态下面的查询提交 
        * @return boolen 
        */
        public function commit() {
            $result = true;
            if ($this->_trans>0) { 
                $result = self::$_dbh->commit(); 
                $this->_trans = 0;
            } 
            return $result;
        }

        /** 
        * 事务回滚 
        * @return boolen 
        */
        public function rollback() {
            $result = true;
            if ($this->_trans>0) {
                $result = self::$_dbh->rollback();
                $this->_trans = 0;
            }
            return $result;
        }

        /**
        * 关闭连接
        * PHP 在脚本结束时会自动关闭连接。
        */
        public function close() {
            if (!is_null(self::$_dbh)) self::$_dbh = null;
        }

}

PHP进行tcp连接

原生PHP的写法。

$host = '服务端IP';
    $port = 端口号;
    $timeout = 5;

    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if (socket_connect($socket, $host, $port) === false) { // 创建连接
        socket_close($socket);
        $message = 'create socket error';
        throw new Exception($message, socket_last_error());
    }   

    if (socket_write($socket, $buffer) === false) { // 发包
        socket_close($socket);
        $message = sprintf("write socket error:%s", socket_strerror(socket_last_error()));
        throw new Exception($message, socket_last_error());
    }   

    socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $timeout);

    $rspBuffer = socket_read($socket, 65536); // 接收回包

    socket_close($socket);

使用swoole的写法。

$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
$ret = $client->connect('服务端IP', 端口号, 0.5, 0);  // 创建连接
if (!$ret) {
    throw new Exception('connect error', $client->errCode);
}   

$client->send($buffer); // 发包

$rspBuffer = $client->recv(); // 接收回包

转载地址

https://www.liudon.org/1324.html

php hex16进制数据 BBC异或值计算

1.前言
物联网的通信。想要远程通信,必须要用指定的协议发送给机器才可以实现智能开锁。需要发送的数据是16进制的hex,并且最后一位的数据必须用BBC异或校验得到的数据才行。网上查询了一下php生成BBC异或校验码的相关资料,记录一下
在线效验异或值地址:http://www.metools.info/code/c48.html,
http://www.ip33.com/bcc.html

BBC校验
BCC(Block Check Character/信息组校验码),因校验码是将所有数据异或得出,故俗称异或校验。具体算法是:将每一个字节的数据(一般是两个16进制的字符)进行异或后即得到校验码。
例如16进制数据:01 A0 7C FF 02
计算:01 xor A0 xor 7C xor FF xor 02 = 20
校验码是:20

计算思路
把十六进制的字符按照顺序两个异或之后拿得到的结果再和下一个异或,

hex数据BBC异或校验(两两比较)
/**
* @param $byte1
* @param $byte2
* @return string
* hex数据BBC异或校验(两两比较)
*/
function hexOr($byte1, $byte2)
{
$result=”;
$byte1= str_pad(base_convert($byte1, 16, 2), ‘8’, ‘0’, STR_PAD_LEFT);
$byte2= str_pad(base_convert($byte2, 16, 2), ‘8’, ‘0’, STR_PAD_LEFT);
$len1 = strlen($byte1);
for ($i = 0; $i < $len1 ; $i++) {
$result .= $byte1[$i] == $byte2[$i] ? ‘0’ : ‘1’;
}
return strtoupper(base_convert($result, 2, 16));
}

hex数据BBC异或校验(多个hex数据进行校验)
/**
* @param $data
* @return mixed
* hex数据BBC异或校验(多个hex数据进行校验)
*/
function hexOrArr($data)
{
$result = $data[0];
for ($i = 0; $i < count($data) – 1; $i++) {
$result = hexOr($result, $data[$i + 1]);
}
return $result;
}

字符串根据字节长度拆分为数组

/**
* @param $string
* @param int $len
* @return array
* 字符串根据字节长度拆分为数组
*/
function mbStrSplit($string, $len = 1)
{
$start = 0;
$strlen = mb_strlen($string);
while ($strlen) {
$array[] = strtoupper(mb_substr($string, $start, $len, “utf8”));
$string = mb_substr($string, $len, $strlen, “utf8”);
$strlen = mb_strlen($string);
}
return $array;
}
$message=01A07CFF02
$sum=hexOrArr(mbStrSplit($message, 2));//异或值
echo $sum;
————————————————
版权声明:本文为CSDN博主「傅先生的傅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44243111/article/details/112593099

php hexdec()与dechex()十六进制转换为十进制互换

jquery中文网为您提供php hexdec()与dechex()十六进制转换为十进制互换等资源,欢迎您收藏本站,我们将为您提供最新的php hexdec()与dechex()十六进制转换为十进制互换资源

hexdec() 函数把十六进制转换为十进制。

语法
hexdec(hex_string)

<blockquote>echo hexdec(’77’);       //输出119
echo “<br>”;
echo hexdec(dechex(43));      //输出43
echo “<br>”;
echo hexdec(‘3a’);       //输出58</blockquote>
dechex() 函数把十进制转换为十六进制。

语法
dechex(dec_number)

【PHP7】微信小程序用户信息encryptedData解密

微信小程序出来已久,也没时间学习,近期在尝试做一个小程序玩玩,获取用户信息的时候,微信会返回一些数据,包括明文(json格式)的用户基本信息,同时也有一个加密的字段encryptedData,这里面包括了用户基本信息之外还多了一个参数watermark,里面存放的是用户的openid和小程序的appid,但是要得到这些数据就需要后台进行解密,下面我就说一说解密的过程。
小程序encryptedData
官方给了一些示例,网上也有根据这些改进的加解密方法,但是在我(菜鸟)看来都不是很清楚明了。php7.1之后的版本mcrypt扩展已被废弃,但是小程序官方只给了该版本的示例,对于使用php7.1之后版本的服务器来说就要用别的方法加解密了,最好的方法就是使用openssl扩展,这也是php官方推荐的方案。

小提示:在使用微信的wx.request进行POST请求时,服务器用$_POST可能接收不到数据,我是使用get_file_contents('php://input')解决的,接收到的是一个json格式字符串,但是也可以使用别的方法,利用设置header(具体方法不再赘述)。

准备工作#

之前,我在文章中有讲到PHP的AES加解密的方法,今天就是结合该AES类进行操作:
方法①: PHP进行AES/ECB/PKCS7 padding加密的例子(mcrypt)
方法②:PHP进行AES/ECB/PKCS7 padding加密的例子(openssl)

文章中的加密方法对于ECB模式不需要做什么改变,但是微信小程序使用的加密方式是CBC,该方法和ECB的主要表面差别在于CBC需要设置iv向量,而ECB不需要。

示例代码#

Copy
# 将自己的参数进行替换
$str = file_get_contents('https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code');
# 将json字符串转为数组
$data = json_decode($str, true);
# 这里解密用到的key就是获得的session_key,然后对其进行base64_decode操作
$key = base64_decode($data['session_key']);
# iv是微信返回给你的向量,同样进行base64_decode操作
$iv = base64_decode($_GET['iv']);
# 调用aes类,注意解密方法是AES-128-CBC
$aes = Aes::instance($key, 'AES-128-CBC', $iv);
# 对数据进行解密,得到解密后的json字符串
$data = $aes->decrypt($encryptedData);

至此,本记录结束,有问题欢迎给我提出来哦!

作者:凭栏知潇雨

出处:https://www.cnblogs.com/lantor/p/7522314.html

版权:本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。

webuploader一个页面中多实例使用示例

在使用webuploader上传文件过程中,如果同一个页面存在多个上传区域,如一个页面中需要传营业执照和资质证书,营业执照资质证书都允许上传多张图片,可以参考本示例代码

本示例依赖webuploader相关js及css,基础应用不在本例代码,本例代码提供更优雅的复用示例,只是一个思路,大部分可直接复制使用,特殊需求可根据此代码修改

<script type="text/javascript" src="/js/webuploadertool.js"></script>

页面调用div

<div id="zhizhaoUploader">
	<ul class="_queueList">
		<li class="_picker"><img src="/img/upload.png" alt=""></li>
	</ul>
</div>
 
<div id="zizhiUploader">
	<ul class="_queueList">
		<li class="_picker"><img src="/img/upload.png" alt=""></li>
	</ul>
</div>

页面js

<script style="text/javascript">
    var zhizhao,zhizhiaouploader,zizhi,zhizhiuploader;
    jQuery(function () {
        //执照上传成功后的回调操作,此处是将服务器返回的地址以"|"连接
        var zhizhaosucess = function (file, response) {
            console.log(response._raw);
            zhizhaoPath = zhizhaoPath + response._raw + "|";
            console.log(zhizhaoPath);
        };
        //执照上传失败时的操作,此处直接弹框提示
        var zhizhaoerror = function (message) {
            console.log("文件上传失败,message:" + message);
            alertx(message,true);
        };
        zhizhao = new $WebUpload($("#zhizhaoUploader"), '/imageUpload');
        zhizhao.custsuccess = zhizhaosucess;
        zhizhao.custerror = zhizhaoerror;
        zhizhiaouploader = zhizhao.init();
 
        var zizhisucess = function (file, response) {
            console.log(response._raw);
            zizhiPath = zizhiPath + response._raw + "|";
            console.log(zizhiPath);
        };
        var zizhierror = function (message) {
            console.log("文件上传失败,message:" + message);
            alertx(message,true);
        };
        zizhi = new $WebUpload($("#zizhiUploader"), '/imageUpload');
        zizhi.custsuccess = zizhisucess;
        zizhi.custerror = zizhierror;
        zizhiuploader = zizhi.init();
    });
    var zhizhaoPath = "";
    var zizhiPath = "";
    //提交操作
    function step3() {
        var mobile = ${mobile};
        var zhizhaoprogressNum = zhizhiaouploader.getStats().progressNum;
        var zizhiprogressNum = zizhiuploader.getStats().progressNum;
        console.log("zhizhaoprogressNum:"+zhizhaoprogressNum+",zizhiprogressNum:"+zizhiprogressNum)
        if(zhizhaoprogressNum>0||zizhiprogressNum>0){
            alert("文件正在上传中,请等待文件上传完成!");
            return false;
        }
        if(zhizhaoPath.length<1||zizhiPath.length<1){
            alert("营业执照和资质文件必填!");
            return false;
        }
        $.ajax({
            url: "/xxx",
            type: 'POST',
            data: {
                "mobile": mobile,
                "zhizhaoPath": zhizhaoPath,
                "zizhiPath": zizhiPath,
            },
            success: function (data) {
                if (data.code == '100') {
                    alert("注册成功,请等待审核!");
                    top.window.location = "login.html";
                } else {
                    alert(data.message);
                }
            },
            error: function () {
                alert("数据异常");
            }
        })
    }
</script>

webuploadertool.js

(function () {
    var $WebUpload = function (_uploader, url) {
        this._uploader = _uploader;
        this.serverurl = url;
        this.imageExtensions = 'gif,jpg,jpeg,bmp,png';
        this.mimeTypes ='image/gif,image/jpg,image/jpeg,image/bmp,image/png';
        // 缩略图大小
        this.ratio = window.devicePixelRatio || 1,
            this.thumbnailWidth = 160 * this.ratio;
        this.thumbnailHeight = 120 * this.ratio;
        this.fileSizeLimit = 10 * 1024 * 1024;
        this.fileNumLimit = 5;
        this.fileSingleSizeLimit = 10 * 1024 * 1024;
        this.swfurl = BASE_URL + '/js/Uploader.swf';
        this.custsuccess = null;
        this.custerror = null;
        this.fileCount = 0;
        this.WebUploader;
    };
    $WebUpload.prototype = {
        /**
         * 初始化webUploader
         */
        init: function () {
            var uploader = this.create();
            this.bindEvent(uploader);
            return uploader;
        },
 
        /**
         * 创建webuploader对象
         */
        create: function () {
            var webUploader = WebUploader.create({
                pick: $('._picker', $(this._uploader))[0],
                //dnd: $('._queueList', $(this._uploader))[0],
                // 这里如果要一个页面多个实例,有bug
                // https://github.com/fex-team/webuploader/issues/81#issuecomment-228499631
                accept: {
                    title: 'Images',
                    extensions: this.imageExtensions,
                    mimeTypes: this.mimeTypes
                },
                // swf文件路径
                swf: this.swfurl,
                disableGlobalDnd: true,
                duplicate: false,//不允许上传同一个文件
                auto: true,//自动上传
                server: this.serverurl,
                fileNumLimit: this.fileNumLimit,
                fileSingleSizeLimit: this.fileSingleSizeLimit * 1024 * 1024    // 3 M
            });
            return webUploader;
        },
 
        /**
         * 绑定事件
         */
        bindEvent: function (bindedObj) {
            var me = this;
            bindedObj.on('fileQueued', function (file) {
                var $li = $('<li id="' + $(me._uploader).attr("id") + "_" + file.id + '" class="file-item thumbnail">' +
                        '<img id="thumb_' + $(me._uploader).attr("id") + "_" + file.id + '" src="http://img2.bdstatic.com/static/searchresult/img/loading_circle_40b82ef.gif">' +
                        //'<div class="info" style="width: 200px;height: 185px;"><span class="mk" style=" color:#999;border-bottom:none;display: block;width: 200px;height: 30px;">' + file.name + '</span></div>' +
                        '</li>'
                    ),
                    $img = $li.find('img');
                // $list为容器jQuery实例
                $($('._queueList', $(me._uploader))[0]).append($li);
                // 创建缩略图
                // 如果为非图片文件,可以不用调用此方法。
                // thumbnailWidth x thumbnailHeight 为 100 x 100
                // bindedObj.makeThumb(file, function (error, src) {
                //     if (error) {
                //         $img.replaceWith('<span>不能预览</span>');
                //         return;
                //     }
                //     $img.attr('src', src);
                // }, me.thumbnailWidth, me.thumbnailHeight);
                me.fileCount++;
                if (me.fileNumLimit == me.fileCount) {
                    $($('._picker', $(me._uploader))[0]).css("display", "none");
                }
            });
            // 文件上传过程中创建进度条实时显示。
            bindedObj.on('uploadProgress', function (file, percentage) {
                var $li = $('#' + $(me._uploader).attr("id") + "_" + file.id),
                    $percent = $li.find('.progress span');
 
                // 避免重复创建
                if (!$percent.length) {
                    $percent = $('<p class="progress"><span></span></p>')
                        .appendTo($li)
                        .find('span');
                }
 
                $percent.css('width', percentage * 100 + '%');
            });
            // 文件上传成功,给item添加成功class, 用样式标记上传成功。
            bindedObj.on('uploadSuccess', function (file, response) {
                $('#' + $(me._uploader).attr("id") + "_" + file.id).addClass('upload-state-done');
                bindedObj.makeThumb(file, function (error, src) {
                    $img = $('#thumb_' + $(me._uploader).attr("id") + "_" + file.id);
                    if (error) {
                        $img.replaceWith('<span>不能预览</span>');
                        return;
                    }
                    $img.attr('src', src);
                }, me.thumbnailWidth, me.thumbnailHeight);
 
                if ('function' == typeof me.custsuccess) {
                    me.custsuccess(file, response);
                }
            });
 
            // 文件上传失败,显示上传出错。
            bindedObj.on('uploadError', function (file, reason) {
                var $li = $('#' + $(me._uploader).attr("id") + "_" + file.id),
                    $error = $li.find('div.error');
 
                // 避免重复创建
                if (!$error.length) {
                    $error = $('<div class="error"></div>').appendTo($li);
                }
 
                $error.text('上传失败,' + reason);
            });
 
            // 其他错误
            bindedObj.on('error', function (type) {
                console.log("webuploadertool error type:" + type);
                var message = "";
                if ("Q_EXCEED_NUM_LIMIT" == type) {
                    message = "最多只允许上传" + me.fileNumLimit + "张图片";
                } else if ("F_EXCEED_SIZE" == type) {
                    message = "单张只允许上传" + me.fileSingleSizeLimit + "M以内的图片";
                } else if ("Q_TYPE_DENIED" == type) {
                    message = "只允许上传类型为" + me.imageExtensions + "的图片";
                }
                if ('function' == typeof me.custerror) {
                    me.custerror(message);
                }
            });
 
            // 完成上传完了,成功或者失败
            bindedObj.on('uploadComplete', function (file) {
                $('#' + $(me._uploader).attr("id") + "_" + file.id).find('.progress').remove();
            });
        }
    };
    window.$WebUpload = $WebUpload;
}());

 

利用WebUploader实现大文件上传和视频上传

文件上传是网站开发必不可少的,常见的有图片上传。但是大文件和视频上传不常见。这里我将自己写的视频上传demo贴出来供大家参考:

利用是最新的WebUploader插件请 下载使用最新版即可

js代码

_extensions ='3gp,mp4,rmvb,mov,avi,m4v';  
    _mimeTypes ='video/*,audio/*,application/*';  
  
$(function(){              
    var chunkSize = 500 * 1024;        //分块大小  
    var uniqueFileName = null;          //文件唯一标识符  
    var md5Mark = null;  
  
    // var _backEndUrl = '';  
  
    WebUploader.Uploader.register({  
        "before-send-file": "beforeSendFile"  
        , "before-send": "beforeSend"  
        , "after-send-file": "afterSendFile"  
    }, {  
        beforeSendFile: function(file){  
            console.log(file);  
            //秒传验证  
            var task = new $.Deferred();  
            var start = new Date().getTime();  
            (new WebUploader.Uploader()).md5File(file, 0, 10*1024*1024).progress(function(percentage){  
            }).then(function(val){  
  
                md5Mark = val;  
                _userInfo.md5 = val;  
  
                $.ajax({  
                    type: "POST",  
                    url: _backEndUrl,  
                    data: {  
                        status: "md5Check",  
                        md5: val  
                    },  
                    cache: false,  
                    timeout: 1000, //todo 超时的话,只能认为该文件不曾上传过  
                    dataType: "json"  
                }).then(function(data, textStatus, jqXHR){  
  
                    if(data.ifExist){   //若存在,这返回失败给WebUploader,表明该文件不需要上传  
                        task.reject();  
  
                        uploader.skipFile(file);  
                        file.path = data.path;  
                        UploadComlate(file);  
                    }else{  
                        task.resolve();  
                        //拿到上传文件的唯一名称,用于断点续传  
                        uniqueFileName = md5(_userInfo.openid+_userInfo.time);  
                    }  
                }, function(jqXHR, textStatus, errorThrown){    //任何形式的验证失败,都触发重新上传  
                    task.resolve();  
                    //拿到上传文件的唯一名称,用于断点续传  
                    uniqueFileName = md5(_userInfo.openid+_userInfo.time);  
                });  
            });  
            return $.when(task);  
        }  
        , beforeSend: function(block){  
            //分片验证是否已传过,用于断点续传  
            var task = new $.Deferred();  
            $.ajax({  
                type: "POST"  
                , url: _backEndUrl  
                , data: {  
                    status: "chunkCheck"  
                    , name: uniqueFileName  
                    , chunkIndex: block.chunk  
                    , size: block.end - block.start  
                }  
                , cache: false  
                , timeout: 1000 //todo 超时的话,只能认为该分片未上传过  
                , dataType: "json"  
            }).then(function(data, textStatus, jqXHR){  
                if(data.ifExist){   //若存在,返回失败给WebUploader,表明该分块不需要上传  
                    task.reject();  
                }else{  
                    task.resolve();  
                }  
            }, function(jqXHR, textStatus, errorThrown){    //任何形式的验证失败,都触发重新上传  
                task.resolve();  
            });  
  
            return $.when(task);  
        }  
        , afterSendFile: function(file){  
            var chunksTotal = 0;  
            if((chunksTotal = Math.ceil(file.size/chunkSize)) > 1){  
                //合并请求  
                var task = new $.Deferred();  
                $.ajax({  
                    type: "POST"  
                    , url: _backEndUrl  
                    , data: {  
                        status: "chunksMerge"  
                        , name: uniqueFileName  
                        , chunks: chunksTotal  
                        , ext: file.ext  
                        , md5: md5Mark  
                    }  
                    , cache: false  
                    , dataType: "json"  
                }).then(function(data, textStatus, jqXHR){  
  
                    //todo 检查响应是否正常  
  
                    task.resolve();  
                    file.path = data.path;  
                    UploadComlate(file);  
  
                }, function(jqXHR, textStatus, errorThrown){  
                    task.reject();  
                });  
  
                return $.when(task);  
            }else{  
                UploadComlate(file);  
            }  
        }  
    });  
  
    var uploader = WebUploader.create({  
        swf: "./Uploader.swf",  
        server: _backEndUrl,     //服务器处理文件的路径  
        pick: "#picker",        //指定选择文件的按钮,此处放的是id  
        resize: false,   
        dnd: "#theList",        //上传文件的拖拽容器(即,如果选择用拖拽的方式选择文件进行上传,应该要把文件拖拽到的区域容器)  
        paste: document.body,   //[可选] [默认值:undefined]指定监听paste事件的容器,如果不指定,不启用此功能。此功能为通过粘贴来添加截屏的图片。建议设置为document.body  
        disableGlobalDnd: true, //[可选] [默认值:false]是否禁掉整个页面的拖拽功能,如果不禁用,图片拖进来的时候会默认被浏览器打开。  
        compress: false,  
        prepareNextFile: true,   
        chunked: true,   
        chunkSize: chunkSize,  
        chunkRetry: 2,    //[可选] [默认值:2]如果某个分片由于网络问题出错,允许自动重传多少次?  
        threads: true,      //[可选] [默认值:3] 上传并发数。允许同时最大上传进程数。  
        formData: function(){return $.extend(true, {}, _userInfo);},   
        fileNumLimit: 1,   
        fileSingleSizeLimit: 50 * 1024 * 1024,// 限制在50M  
        duplicate: true,  
        accept: {        
            title: '大文件上传',  //文字描述  
            extensions: _extensions,     //允许的文件后缀,不带点,多个用逗号分割。,jpg,png,  
            mimeTypes: _mimeTypes,      //多个用逗号分割。image/*,  
        },  
    });  
  
    /**  
     * 验证文件格式以及文件大小  
     */  
    uploader.on("error",function (type,handler){  
        if (type=="Q_TYPE_DENIED"){  
            swal({  
                title:'',  
                text: '请上传MP4格式的视频~',  
                type: "warning",  
                confirmButtonColor: "#DD6B55",  
                confirmButtonText: "我知道了",  
            });  
        }else if(type=="F_EXCEED_SIZE"){  
            swal({  
                title:'',  
                text: '视频大小不能超过50M哦~',  
                type: "warning",  
                confirmButtonColor: "#DD6B55",  
                confirmButtonText: "我知道了",  
            });  
        }  
    });  
  
    uploader.on("fileQueued", function(file){  
        $('#theList').show();  
        $("#theList").append('<li id="'+file.id+'" class="upload_li">' +  
            ' <img /> <span class="file_name upload_li">'+file.name+'</span></li><li class="upload_li"><span class="itemUpload weui-btn weui-btn_mini weui-btn_primary">上传</span><span class="itemStop weui-btn weui-btn_mini weui-btn_default">暂停</span><span class="itemDel weui-btn weui-btn_mini weui-btn_warn">删除</span></li><li class="upload_li">' +  
            '<div id="percentage'+file.id+'" class="percentage"><div class="weui-progress__bar"><div class="weui-progress__inner-bar js_progress" style="width: 0%;"></div> <b id="pers"></b> </div></div>' +  
        '</li>');  
          
        var $img = $("#" + file.id).find("img");  
          
        uploader.makeThumb(file, function(error, src){  
            if(error){  
                $img.replaceWith("<span class='no_view'>视频暂不能预览</span>");  
            }  
  
            $img.attr("src", src);  
        });  
          
    });  
      
    $("#theList").on("click", ".itemUpload", function(){  
        uploader.upload();  
  
        //"上传"-->"暂停"  
        $(this).hide();  
        $(".itemStop").css('display','inline-block');  
        $(".itemStop").show();  
    });  
  
    $("#theList").on("click", ".itemStop", function(){  
        uploader.stop(true);  
  
        //"暂停"-->"上传"  
        $(this).hide();  
        $(".itemUpload").show();  
    });  
  
    //todo 如果要删除的文件正在上传(包括暂停),则需要发送给后端一个请求用来清除服务器端的缓存文件  
    $("#theList").on("click", ".itemDel", function(){  
        uploader.removeFile($('.upload_li').attr("id"));    //从上传文件列表中删除  
  
        $('.upload_li').remove();   //从上传列表dom中删除  
    });  
      
    uploader.on("uploadProgress", function(file, percentage){  
        $(".percentage").find('.js_progress').css("width",percentage * 100 + "%");  
        $(".percentage").find('#pers').text(parseInt(percentage * 100) + "%");  
    });  
  
    function UploadComlate(file){  
        console.log(file);  
        if(file && file.name){  
            $('#vedio').val(file.name);  
            $(".percentage").find('#pers').html("<span style='color:green;'>上传完毕</span>");  
            $(".itemStop").hide();  
            $(".itemUpload").hide();  
            $(".itemDel").hide();  
        }else{  
            $(".percentage").find('#pers').html("<span style='color:red;'>上传失败,请您检查网络状况~</span>");  
            $(".itemStop").hide();  
            $(".itemUpload").hide();  
        }  
  
    }  
  
})  

PHP控制器

public function vupload(){  
        set_time_limit (0);  
        //关闭缓存  
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");  
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");  
        header("Cache-Control: no-store, no-cache, must-revalidate");  
        header("Cache-Control: post-check=0, pre-check=0", false);  
        header("Pragma: no-cache");  
  
        $ip_path = './uploads/'.$_SESSION['userinfo']['id'];  
        $save_path = 'uploads/'.$_SESSION['userinfo']['id'];  
        $uploader =  new \Org\Util\Vupload;  
        $uploader->set('path',$ip_path);  
        //用于断点续传,验证指定分块是否已经存在,避免重复上传  
        if(isset($_POST['status'])){  
            if($_POST['status'] == 'chunkCheck'){  
                $target =  $ip_path.'/'.$_POST['name'].'/'.$_POST['chunkIndex'];  
                if(file_exists($target) && filesize($target) == $_POST['size']){  
                    die('{"ifExist":1}');  
                }  
                die('{"ifExist":0}');  
  
            }elseif($_POST['status'] == 'md5Check'){  
  
                //todo 模拟持久层查询  
                $dataArr = array(  
                    'b0201e4d41b2eeefc7d3d355a44c6f5a' => 'kazaff2.jpg'  
                );  
  
                if(isset($dataArr[$_POST['md5']])){  
                    die('{"ifExist":1, "path":"'.$dataArr[$_POST['md5']].'"}');  
                }  
                die('{"ifExist":0}');  
            }elseif($_POST['status'] == 'chunksMerge'){  
  
                if($path = $uploader->chunksMerge($_POST['name'], $_POST['chunks'], $_POST['ext'])){  
                    //todo 把md5签名存入持久层,供未来的秒传验证  
                    session('video_path', $save_path.'/'.$path);  
                    die('{"status":1, "path": "'.$save_path.'/'.$path.'"}');  
                }  
                die('{"status":0}');  
            }  
        }  
  
        if(($path = $uploader->upload('file', $_POST)) !== false){  
            if(!session('video_path')){  
                session('video_path', $save_path.'/'.$path);  
            }  
            die('{"status":1, "path": "'.$save_path.'/'.$path.'"}');  
        }  
        die('{"status":0}');  
    }  

封装的上传类库

<?php  
/** 
 * 
 * 版权所有:重庆市环境保护信息中心 
 * 作    者:Sqc 
 * 日    期:2016-12-06 
 * 版    本:1.0.0 
 * 功能说明:用于视频等上传。 
 * 
 **/  
namespace Org\Util;  
Class Vupload  
{     
    //要配置的内容  
    private $path = "./uploads";  
    private $allowtype = array('jpg', 'gif', 'png', 'mp4', 'mp3','3gp','rmvb','mov','avi','m4v');  
    private $maxsize = 104857600;//  
    private $israndname = true;  
  
    private $originName;  
    private $tmpFileName;  
    private $fileType;  
    private $fileSize;  
    private $newFileName;  
    private $errorNum = 0;  
    private $errorMess = "";  
      
    private $isChunk = false;  
    private $indexOfChunk = 0;  
  
    public function _initialize(){  
        parent::_initialize();  
    }  
  
    /** 
     * 用于设置成员属性($path, $allowtype, $maxsize, $israndname) 
     * 可以通过连贯操作一次设置多个属性值 
     * @param $key  成员属性(不区分大小写) 
     * @param $val  为成员属性设置的值 
     * @return object 返回自己对象$this, 可以用于连贯操作 
     */  
    function set($key, $val){  
        $key = strtolower($key);  
        if (array_key_exists($key, get_class_vars(get_class($this)))){  
            $this->setOption($key, $val);  
        }  
        return $this;  
    }  
  
    /** 
     * 调用该方法上传文件 
     * Enter description here ... 
     * @param $fileField    上传文件的表单名称 
     * 
     */  
    function upload($fileField, $info){  
      
        //判断是否为分块上传  
        $this->checkChunk($info);  
          
        if (!$this->checkFilePath($this->path)){  
            $this->errorMess = $this->getError();  
            return false;  
        }  
  
        //将文件上传的信息取出赋给变量  
        $name = $_FILES[$fileField]['name'];  
        $tmp_name = $_FILES[$fileField]['tmp_name'];  
        $size = $_FILES[$fileField]['size'];  
        $error = $_FILES[$fileField]['error'];  
  
  
        //设置文件信息  
        if ($this->setFiles($name, $tmp_name, $size, $error)){  
          
            //如果是分块,则创建一个唯一名称的文件夹用来保存该文件的所有分块  
            if($this->isChunk){  
                $uploadDir = $this->path;  
                if($info){  
                    $tmpName = $this->setDirNameForChunks();  
                     
                     if(!$this->checkFilePath($uploadDir . '/' . $tmpName)){  
                        $this->errorMess = $this->getError();  
                        return false;  
                    }  
                }  
        //         $tmpName = $this->setDirNameForChunks($info);  
        //         if(!$this->checkFilePath($uploadDir . '/' . $tmpName)){  
                    // $this->errorMess = $this->getError();  
        //          return false;  
        //         }  
                  
                //创建一个对应的文件,用来记录上传分块文件的修改时间,用于清理长期未完成的垃圾分块  
                touch($uploadDir.'/'.$tmpName.'.tmp');  
            }  
  
            if($this->checkFileSize() && $this->checkFileType()){  
                $this->setNewFileName();  
                if ($this->copyFile()){  
                    return $this->newFileName;  
                }  
            }  
        }  
  
        $this->errorMess = $this->getError();  
        return false;  
    }  
  
    public function chunksMerge($uniqueFileName, $chunksTotal, $fileExt){  
        $targetDir = $this->path.'/'.$uniqueFileName;  
        //检查对应文件夹中的分块文件数量是否和总数保持一致  
        if($chunksTotal > 1 && (count(scandir($targetDir)) - 2) == $chunksTotal){  
            //同步锁机制  
            $lockFd = fopen($this->path.'/'.$uniqueFileName.'.lock', "w");  
            if(!flock($lockFd, LOCK_EX | LOCK_NB)){  
                fclose($lockFd);  
                return false;  
            }  
  
            //进行合并  
            $this->fileType = $fileExt;  
            $finalName = $this->path.'/'.($this->setOption('newFileName', $this->proRandName()));  
            $file = fopen($finalName, 'wb');  
            for($index = 0; $index < $chunksTotal; $index++){  
                $tmpFile = $targetDir.'/'.$index;  
                $chunkFile = fopen($tmpFile, 'rb');  
                $content = fread($chunkFile, filesize($tmpFile));  
                fclose($chunkFile);  
                fwrite($file, $content);  
  
                //删除chunk文件  
                unlink($tmpFile);  
            }  
            fclose($file);  
            //删除chunk文件夹  
            rmdir($targetDir);  
            unlink($this->path.'/'.$uniqueFileName.'.tmp');  
  
            //解锁  
            flock($lockFd, LOCK_UN);  
            fclose($lockFd);  
            unlink($this->path.'/'.$uniqueFileName.'.lock');  
  
            return $this->newFileName;  
  
        }  
        return false;  
    }  
  
    //获取上传后的文件名称  
    public function getFileName(){  
        return $this->newFileName;  
    }  
  
    //上传失败后,调用该方法则返回,上传出错信息  
    public function getErrorMsg(){  
        return $this->errorMess;  
    }  
  
    //设置上传出错信息  
    public function getError(){  
        $str = "上传文件<font color='red'>{$this->originName}</font>时出错:";  
        switch ($this->errorNum) {  
            case 4:  
                $str.= "没有文件被上传";  
                break;  
            case 3:  
                $str.= "文件只有部分被上传";  
                break;  
            case 2:  
                $str.= "上传文件的大小超过了HTML表单中MAX_FILE_SIZE选项指定的值";  
                break;  
            case 1:  
                $str.= "上传的文件超过了php.ini中upload_max_filesize选项限制的值";  
                break;  
            case -1:  
                $str.= "未允许的类型";  
                break;  
            case -2:  
                $str.= "文件过大, 上传的文件夹不能超过{$this->maxsize}个字节";  
                break;  
            case -3:  
                $str.= "上传失败";  
                break;  
            case -4:  
                $str.= "建立存放上传文件目录失败,请重新指定上传目录";  
                break;  
            case -5:  
                $str.= "必须指定上传文件的路径";  
                break;  
  
            default:  
                $str .= "未知错误";  
        }  
        return $str."<br>";  
    }  
  
    //根据文件的相关信息为分块数据创建文件夹  
    //md5(当前登录用户的数据库id + 文件原始名称 + 文件类型 + 文件最后修改时间 + 文件总大小)  
    private function setDirNameForChunks(){  
        $str = $_SESSION['userinfo']['openid'].$_SESSION['userinfo']['report_time'];  
        return md5($str);  
        return $str;   
    }  
  
    //设置和$_FILES有关的内容  
    private function setFiles($name="", $tmp_name="", $size=0, $error=0){  
        $this->setOption('errorNum', $error);  
        if ($error) {  
            return false;  
        }  
        $this->setOption('originName', $name);  
        $this->setOption('tmpFileName', $tmp_name);  
        $aryStr = explode(".", $name);  
        $this->setOption("fileType", strtolower($aryStr[count($aryStr)-1]));  
        $this->setOption("fileSize", $size);  
        return true;  
    }  
  
    private function checkChunk($info){  
        if(isset($info['chunks']) && $info['chunks'] > 0){  
            $this->setOption("isChunk", true);  
              
            if(isset($info['chunk']) && $info['chunk'] >= 0){  
                $this->setOption("indexOfChunk", $info['chunk']);  
                  
                return true;  
            }  
              
            throw new Exception('分块索引不合法');  
        }  
          
        return false;  
    }  
  
    //为单个成员属性设置值  
    private function setOption($key, $val){  
        $this->$key = $val;  
        return $val;  
    }  
  
    //设置上传后的文件名称  
    private function setNewFileName(){  
        if($this->isChunk){     //如果是分块,则以分块的索引作为文件名称保存  
            $this->setOption('newFileName', $this->indexOfChunk);  
        }elseif($this->israndname) {  
            $this->setOption('newFileName', $this->proRandName());  
        }else{  
            $this->setOption('newFileName', $this->originName);  
        }  
    }  
  
    //检查上传的文件是否是合法的类型  
    private function checkFileType(){  
        if (in_array(strtolower($this->fileType), $this->allowtype)) {  
            return true;  
        }else{  
            $this->setOption('errorNum', -1);  
            return false;  
        }  
    }  
  
  
    //检查上传的文件是否是允许的大小  
    private function checkFileSize(){  
        if ($this->fileSize > $this->maxsize) {  
            $this->setOption('errorNum', -5);  
            return false;  
        }else{  
            return true;  
        }  
    }  
  
    //检查是否有存放上传文件的目录  
    private function checkFilePath($target){  
          
        if (empty($target)) {  
            $this->setOption('errorNum', -5);  
            return false;  
        }  
          
        if (!file_exists($target) || !is_writable($target)) {  
            if (!@mkdir($target, 0755)) {  
                $this->setOption('errorNum', -4);  
                return false;  
            }  
        }  
  
        $this->path = $target;  
        return true;  
    }  
  
    //设置随机文件名  
    private function proRandName(){  
        $fileName = date('YmdHis')."_".rand(100,999);  
        return $fileName.'.'.$this->fileType;  
    }  
  
    //复制上传文件到指定的位置  
    private function copyFile(){  
        if (!$this->errorNum) {  
            $path = rtrim($this->path, '/').'/';  
            $path.= $this->newFileName;  
            if (@move_uploaded_file($this->tmpFileName, $path)) {  
                return true;  
            }else{  
                $this->setOption('errorNum', -3);  
                return false;  
            }  
        }else{  
            return false;  
        }  
    }  
}  

 

超级有用的9个PHP代码片段

在开发网站、app或博客时,代码片段可以真正地为你节省时间。今天,我们就来分享一下我收集的一些超级有用的PHP代码片段。一起来看一看吧!

1.创建数据URI

数据URI在嵌入图像到HTML / CSS / JS中以节省HTTP请求时非常有用,并且可以减少网站的加载时间。下面的函数可以创建基于$file的数据URI。

function data_uri($file, $mime) {
 $contents=file_get_contents($file);
 $base64=base64_encode($contents);
 echo "data:$mime;base64,$base64";
}

2.合并JavaScript和CSS文件

另一个可以尽量减少HTTP请求和节省页面加载时间的好建议是:合并你的CSS和JS文件。虽然我更建议大家使用专用插件(例如minify),但使用PHP来合并文件也非常容易。我们来看一下:

function combine_my_files($array_files, $destination_dir, $dest_file_name){
 if(!is_file($destination_dir . $dest_file_name)){ //continue only if file doesn't exist
 $content = "";
 foreach ($array_files as $file){ //loop through array list
 $content .= file_get_contents($file); //read each file
 }
 //You can use some sort of minifier here
 //minify_my_js($content);
 $new_file = fopen($destination_dir . $dest_file_name, "w" ); //open file for writing
 fwrite($new_file , $content); //write to destination
 fclose($new_file);
 return '<script src="'.%20$destination_dir%20.%20$dest_file_name.'"></script>'; //output combined file
 }else{
 //use stored file
 return '<script src="'.%20$destination_dir%20.%20$dest_file_name.'"></script>'; //output combine file
 }
}

并且,用法是这样的:

$files = array(
 'http://example/files/sample_js_file_1.js',
 'http://example/files/sample_js_file_2.js',
 'http://example/files/beautyquote_functions.js',
 'http://example/files/crop.js',
 'http://example/files/jquery.autosize.min.js',
 );
echo combine_my_files($files, 'minified_files/', md5("my_mini_file").".js");

3.查看你的电子邮件是否已读

当发送电子邮件时,你会希望知道你的邮件是否已读。这里有一个非常有趣的代码片段,它可以记录阅读你邮件的IP地址,以及实际的日期和时间。

<?
error_reporting(0);
Header("Content-Type: image/jpeg");
//Get IP
if (!empty($_SERVER['HTTP_CLIENT_IP']))
{
  $ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
  $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
  $ip=$_SERVER['REMOTE_ADDR'];
}
//Time
$actual_time = time();
$actual_day = date('Y.m.d', $actual_time);
$actual_day_chart = date('d/m/y', $actual_time);
$actual_hour = date('H:i:s', $actual_time);
//GET Browser
$browser = $_SERVER['HTTP_USER_AGENT'];
//LOG
$myFile = "log.txt";
$fh = fopen($myFile, 'a+');
$stringData = $actual_day . ' ' . $actual_hour . ' ' . $ip . ' ' . $browser . ' ' . "\r\n";
fwrite($fh, $stringData);
fclose($fh);
//Generate Image (Es. dimesion is 1x1)
$newimage = ImageCreate(1,1);
$grigio = ImageColorAllocate($newimage,255,255,255);
ImageJPEG($newimage);
ImageDestroy($newimage);
?>

4.从网页提取关键词

正如这小标题所说的那样:这个代码片段能让你轻易地从网页中提取元关键词。

$meta = get_meta_tags('http://www.emoticode.net/');
$keywords = $meta['keywords'];
// Split keywords
$keywords = explode(',', $keywords );
// Trim them
$keywords = array_map( 'trim', $keywords );
// Remove empty values
$keywords = array_filter( $keywords );
print_r( $keywords );

5.查找页面上的所有链接

使用DOM,你可以轻松地抓取来网页上的所有链接。这里有一个工作示例:

$html = file_get_contents('http://www.example.com');
$dom = new DOMDocument();
@$dom->loadHTML($html);
// grab all the on the page
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate("/html/body//a");
for ($i = 0; $i < $hrefs->length; $i++) {
 $href = $hrefs->item($i);
 $url = $href->getAttribute('href');
 echo $url.'<br />';
}

6.自动转换URL为可点击的超链接

在WordPress中,如果你想在字符串中自动转换所有的URL成可点击的超链接,那么使用内置函数make_clickable()可以让你心想事成。如果你需要在WordPress之外这么做,那么你可以在wp-includes/formatting.php参考该函数的源代码:

function _make_url_clickable_cb($matches) {
$ret = '';
$url = $matches[2];
if ( empty($url) )
return $matches[0];
// removed trailing [.,;:] from URL
if ( in_array(substr($url, -1), array('.', ',', ';', ':')) === true ) {
$ret = substr($url, -1);
$url = substr($url, 0, strlen($url)-1);
}
return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>" . $ret;
}
function _make_web_ftp_clickable_cb($matches) {
$ret = '';
$dest = $matches[2];
$dest = 'http://' . $dest;
if ( empty($dest) )
return $matches[0];
// removed trailing [,;:] from URL
if ( in_array(substr($dest, -1), array('.', ',', ';', ':')) === true ) {
$ret = substr($dest, -1);
$dest = substr($dest, 0, strlen($dest)-1);
}
return $matches[1] . "<a href=\"$dest\" rel=\"nofollow\">$dest</a>" . $ret;
}
function _make_email_clickable_cb($matches) {
$email = $matches[2] . '@' . $matches[3];
return $matches[1] . "<a href=\"mailto:$email\">$email</a>";
}
function make_clickable($ret) {
$ret = ' ' . $ret;
// in testing, using arrays here was found to be faster
$ret = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_url_clickable_cb', $ret);
$ret = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_web_ftp_clickable_cb', $ret);
$ret = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret);
// this one is not in an array because we need it to run last, for cleanup of accidental links within links
$ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);
$ret = trim($ret);
return $ret;
}

7.在你的服务器上下载并保存远程图像

在远程服务器上下载一个图像,并将其保存在自己的服务器上,在建立网站时很有用,而且这也很容易做到。下面的这两行代码就能为你办到。

$image = file_get_contents('http://www.url.com/image.jpg');
file_put_contents('/images/image.jpg', $image); //Where to save the image

8.检测浏览器语言

如果你的网站使用多种语言,那么检测浏览器语言,并将这种语言作为默认语言会很有用。下面的代码将返回客户浏览器使用的语言。

function get_client_language($availableLanguages, $default='en'){
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$langs=explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
foreach ($langs as $value){
$choice=substr($value,0,2);
if(in_array($choice, $availableLanguages)){
return $choice;
}
}
} 
return $default;
}

9.全文显示Facebook粉丝的数量

如果你的网站或博客有一个Facebook的页面,那么你可能想要显示你有多少个粉丝。这个代码片段可以帮助你获取Facebook粉丝的数量。不要忘记在第二行添加你的页面ID。页面ID可以在地址http://facebook.com/yourpagename/info找到。

<?php
$page_id = "302807633129400";
$xml = @simplexml_load_file("http://api.facebook.com/restserver.php?method=facebook.fql.query&query=SELECT%20fan_count%20FROM%20page%20WHERE%20page_id=".$page_id."") or die ("a lot");
$fans = $xml->page->fan_count;
echo $fans;
?>

译文链接:http://www.codeceo.com/article/9-useful-php-code-snippets.html
英文原文:Super Useful PHP Snippets
翻译作者:码农网 – 小峰
转载必须在正文中标注并保留原文链接、译文链接和译者等信息。]