PHP实用代码段

服务器推

<?php
set_time_limit(0);
while (@ ob_end_clean()); // 关闭之前的缓存区
ob_start();
$i = 1;
while (true) {
    echo $i . '<br/>';
    ob_flush(); 
    flush();
    sleep(1);
}

// 大致原理, 这个页面嵌套到iframe中, 循环从数据库从取出消息, 如果有未读消息, 输出javascript代码
// $str = '从数据库取出的消息';
// echo "<script>parent.showMsg($str)</script>";

二维数组排序

$guys = array(
    array(
        'name' => 'jake',
        'score' => 80,
        'grade' => 'A'
    ),
    array(
        'name' => 'jin',
        'score' => 70,
        'grade' => 'A'
    ),
    array(
        'name' => 'john',
        'score' => 80,
        'grade' => 'A'
    ),
    array(
        'name' => 'ben',
        'score' => 20,
        'grade' => 'B'
    )
);
//例如我们想按成绩倒序排列,如果成绩相同就按名字的升序排列,这时候就可以用array_multisort排序

$scores = array(80, 70, 80, 20);
$names = array('jake', 'jin', 'john', 'ben');

array_multisort($scores, SORT_DESC, $names, $guys);

//结果是每个数组对应的位置跟着$scores降序排序
var_dump($scores);
var_dump($names);
var_dump($guys);


/**
 * [list_orderByCol description]
 * @param  [array] $array   [进行排序的二维数组]
 * @param  [array]  $args   [排序要求,如array('id' => SORT_DESC)]
 * @return [array]          [返回排序后的数组]
 */
function list_orderByCol($array,$args) {
    $orderArr = array();
    $order = '';
    foreach($array as $row) {
        foreach($row as $field => $value) {
            $orderArr[$field][] = $value;
        }
    }
    foreach($args as $field => $dir) {
        if(!in_array($dir,array(SORT_DESC,SORT_ASC))) {
            return FALSE;
        }
        $order .= '$orderArr[\'' . $field .'\']' . ',' . $dir . ',';
    }
    if(empty($orderArr) || empty($order)) {
        return FALSE;
    }
    //eval注意是要语句格式正确!!!
    eval('array_multisort(' . $order . '$array);');
    return $array;
}
/**
 * 对二维数组进行排序
 * 模拟 数据表记录按字段排序
 *
 * <code>
 *  @list_order($list, $get['orderKey'], $get['orderType']);
 * </code>
 * @param array $array 要排序的数组
 * @param string $orderKey 排序关键字/字段
 * @param string $orderType 排序方式,'asc':升序,'desc':降序
 * @param string $orderValueType 排序字段值类型,'number':数字,'string':字符串
 * @link http://www.php-note.com/article/detail/6eab2985dd5a49a98e6b4ee81bc5922f
 */
function list_order(&$array, $orderKey, $orderType = 'asc', $orderValueType = 'string')
{
    if (is_array($array))
    {
        $orderArr = array();
        foreach ($array as $val)
        {
            $orderArr[] = $val[$orderKey];
        }
        var_dump($orderArr);
        $orderType = ($orderType == 'asc') ? SORT_ASC : SORT_DESC;
        $orderValueType = ($orderValueType == 'string') ? SORT_STRING : SORT_NUMERIC;
        array_multisort($orderArr, $orderType, $orderValueType, $array);
    }
}

几种自动加载方式

function __autoload($class){         
    //比如new Libralies\Databases\Driver\Mysql();
    
    $dir = './libralies';
    
    //把$dir加入预定义引入路径
    
    set_include_path(get_include_path(). PATH_SEPARATOR. $dir);
    
    //PATH_SEPARATOR:include路径分界符号
    //echo get_include_path();
    //结果:  . ; C:\php\pear; ./libralies

    $class = str_replace('\\', '/', $class) . '.php'; 
    
    require_once($class);
}
/*
说明 :
1.如果在指定的目录下找不到所要求包含的文件,而在当前页面目录下正好存在这个名称的文件时,则默认引入当前目录下的该文件。
2.当指定了多个目录为 include_path ,而所要求包含的文件在这几个目录都有相同名称的文件存在时,php选择使用设定 include_path 时排位居前的目录下的文件
*/
function __autoload(){
    $dir = './libralies';
    set_include_path(get_include_path(). PATH_SEPARATOR. $dir);
    $class = str_replace('\\', '/', $class) . '.php'; 
    require_once($class);
}
$a = new Libralies\Databases\Driver\Mysql;
/*
    PSR-4 自动加载实现

    \Foo\Bar\Admin\Action    => /path/to/project/src/Admin/Action

    \Foo\Bar : 命名空间前缀

    __DIR__ . '/src/'  : 文件基目录

    index.php
    src
        - Admin
            - Action.php  (namespace: Foo\Bar\Admin)
 */
spl_autoload_register(function ($class) {
    $prefix   = 'Foo\\Bar\\';
    $base_dir = __DIR__ . '/src/';
    $len      = strlen($prefix);
    // 比较命名空间前缀, 如果不相等,返回
    if (strncmp($prefix,$class,$len) !== 0) {
        return false;
    }
    $relative_class = substr($class,$len);
    // 文件真实路径
    $file = str_replace('\\','/',$base_dir . $relative_class . '.php');
    if (file_exists($file)) {
        require_once($file);
    }
});
$action = new \Foo\Bar\Admin\Action();

/*
    PSR-0 自动加载
    index.php
    src
        - Admin
            - Action.php (namespace: Admin)
 */
spl_autoload_register(function ($class) {
    $base_dir = __DIR__ . '/src/';
    // 把类库基目录添加到include_path
    set_include_path(get_include_path(). PATH_SEPARATOR. $base_dir);
    // 前提:类名映射到目录
    $class = str_replace('\\','/',$class);
    $file  = $base_dir . $class;
    require_once($file);
});
$action = new \Admin\Action();

分页

总行数,
分页数 : ceil(总行数/每页显示行数),
每页显示行数,
当前页(GET获取)>0,
if(当前页 > 总页数) {
    当前页 = 分页数
}
偏移 = (当前页-1)*每页显示行数,

// 关键!!!
function test3($count,$cur) {
    $off = 3;
    if ($count > 2*$off + 1) {   
        if ($cur < $off + 1) {
            $first = 1;
        } else {
            $first = $cur - $off;
        }
        // 根据first算last
        $last = $first + 2*$off;
        if ($last > $count) {
            // 如果超出, 根据last算first
            $last = $count;
            $first = $last- 2*$off;
        }
    } else {
        $first = 1;
        $last = $count;    
    }
}


何时显示第一页 // begin > 1 就显示第一页
何时显示上一页 // 当前页!=1
循环begin->end
何时显示下一页 // 当前页!=total
何时显示最后一页 // end != total 就显示最后一页

flock

flock 共享锁 , 排它锁

1.任何事务都不能获取数据上的排他锁,直到数据已释放所有共享锁

2.共享锁(S锁):如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。 排他锁(X锁):如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

3.共享锁下其它用户可以并发读取,查询数据。但不能修改,增加,删除数据。资源共享

php的flock稍微有点不一样 -- 轻便的咨询文件锁定

参考: http://blog.csdn.net/fdipzone/article/details/43839851

flock()允许执行一个简单的可以在任何平台中使用的读取/写入模型(包括大部分的Unix派生版和windows)
在PHP 5.3.2版本之前,锁会被 fclose() 释放(在脚本结束后会自动调用),现在需要手动解锁

operation
1.LOCK_SH 取得共享锁(读取的程序)
2.LOCK_EX 取得独占锁(写入的程序)
3.LOCK_UN 释放锁定 (无论共享或独占)
4.LOCK_NB 在flock()锁定时不阻塞

家谱树

foreach( array_keys( $list ) as $key )
{
   if( $list[$key]['pid'] == 0 )
   {
        continue;
   }
   if( putChild( $list , $list[$key] ) )// 每条记录都找父节点
   {
        unset( $list[$key] );
   }
}
function putChild( &$list , $tree )
{
    if( empty( $list ) )
    {
        return false;
    }
    foreach( $list as $key => $val )
    {
        if( $tree['pid'] == $val['id'] && $tree['id'] != $tree['pid'] ) // 找父节点, 找到就放到父节点的child数组里面,然后删掉自己
        {
            $list[$key]['child'][] = $tree;
            return true;
        }
        if( isset( $val['child'] ) && is_array( $val['child'] ) && !empty( $val['child'] ) )
        {
            if( putChild( $list[$key]['child'] , $tree ) )
            {
                return true; // 只有return true 才unset
            }
        }
    }
    return false;
}
$list = array(
    1 => array("id"=>'1','pid'=>0,'name'=>'一级栏目一'),
    2 => array("id"=>'2','pid'=>0,'name'=>'一级栏目二'),
    3 => array("id"=>'3','pid'=>1,'name'=>'二级栏目一'),
    4 => array("id"=>'4','pid'=>1,'name'=>'二级栏目二'),
    5 => array("id"=>'5','pid'=>2,'name'=>'二级栏目三'),
    6 => array("id"=>'6','pid'=>3,'name'=>'三级栏目一'),
    7 => array("id"=>'7','pid'=>3,'name'=>'三级栏目二')
);
$menu = getArray(0);
function pre($input) {
    echo '<pre>';
    print_r($input);
    echo '</pre>';
}
pre($menu);
function getChild($id) {
    global $list;
    $arr = '';
    foreach ($list as $row) {
        if ($row['pid'] == $id) {
            $arr[] = $row;
        }
    }
    return $arr;
}   
function getArray($id) {
    global $list;
    $child = getChild($id);
    if (is_array($child)) {
        foreach ($child as $id => $row) {
             $child[$id]['sub'] = getArray($row['id']);
        }
    }
    return $child;
}

无限分类树形格式化

<meta charset="utf-8">
<?php

/**
 * 此方法由@Tonton 提供
 * http://my.oschina.net/u/918697
 * @date 2012-12-12 
 */
function genTree5($items) { 
    foreach ($items as $item) 
        $items[$item['pid']]['son'][$item['id']] = &$items[$item['id']]; 
    return isset($items[0]['son']) ? $items[0]['son'] : array(); 
} 

/**
 * 将数据格式化成树形结构
 * @author Xuefen.Tong
 * @param array $items
 * @return array 
 */
function genTree9($items) {
    $tree = array(); //格式化好的树
    foreach ($items as $item)
        if (isset($items[$item['pid']]))
            $items[$item['pid']]['son'][] = &$items[$item['id']];
        else
            $tree[] = &$items[$item['id']];
    return $tree;
}

$items = array(
    1 => array('id' => 1, 'pid' => 0, 'name' => '江西省'),
    2 => array('id' => 2, 'pid' => 0, 'name' => '黑龙江省'),
    3 => array('id' => 3, 'pid' => 1, 'name' => '南昌市'),
    4 => array('id' => 4, 'pid' => 2, 'name' => '哈尔滨市'),
    5 => array('id' => 5, 'pid' => 2, 'name' => '鸡西市'),
    6 => array('id' => 6, 'pid' => 4, 'name' => '香坊区'),
    7 => array('id' => 7, 'pid' => 4, 'name' => '南岗区'),
    8 => array('id' => 8, 'pid' => 6, 'name' => '和兴路'),
    9 => array('id' => 9, 'pid' => 7, 'name' => '西大直街'),
    10 => array('id' => 10, 'pid' => 8, 'name' => '东北林业大学'),
    11 => array('id' => 11, 'pid' => 9, 'name' => '哈尔滨工业大学'),
    12 => array('id' => 12, 'pid' => 8, 'name' => '哈尔滨师范大学'),
    13 => array('id' => 13, 'pid' => 1, 'name' => '赣州市'),
    14 => array('id' => 14, 'pid' => 13, 'name' => '赣县'),
    15 => array('id' => 15, 'pid' => 13, 'name' => '于都县'),
    16 => array('id' => 16, 'pid' => 14, 'name' => '茅店镇'),
    17 => array('id' => 17, 'pid' => 14, 'name' => '大田乡'),
    18 => array('id' => 18, 'pid' => 16, 'name' => '义源村'),
    19 => array('id' => 19, 'pid' => 16, 'name' => '上坝村'),
);
echo '<pre>';
print_r(genTree5($items));
print_r(genTree9($items));
echo '</pre>'
?>

CURL文件上传

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.exmaple.com/upload');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$params = array();
$src = 'file:/path/to/file';
if (class_exists('\CURLFile')) {
    $fileObj        = new \CURLFile(realpath($src));
    $size           =  getimagesize(realpath($src));
    $fileObj->setMimeType($size['mime']);// 必须指定
    $params['file'] = $fileObj;
} else {
    $params['file'] = '@' . realpath($src);
}
curl_setopt($ch, CURLOPT_POSTFIELDS,  $data);
curl_exec($ch);

标签: none