PHP pack/unpack 的格式字符详细

手册上解释的不是很清楚, 所以网上找了下, 记录下来, 用得着..

string pack ( string $format [, mixed $args [, mixed $...]] )

  • a 一个填充空的字节串
  • A 一个填充空格的字节串
  • b 一个位串,在每个字节里位的顺序都是升序
  • B 一个位串,在每个字节里位的顺序都是降序
  • c 一个有符号 char(8位整数)值
  • C 一个无符号 char(8位整数)值;关于 Unicode 参阅 U
  • d 本机格式的双精度浮点数
  • f 本机格式的单精度浮点数
  • h 一个十六进制串,低四位在前
  • H 一个十六进制串,高四位在前
  • i 一个有符号整数值,本机格式
  • I 一个无符号整数值,本机格式
  • l 一个有符号长整形,总是 32 位
  • L 一个无符号长整形,总是 32 位
  • n 一个 16位短整形,“网络”字节序(大头在前)
  • N 一个 32 位短整形,“网络”字节序(大头在前)
  • p 一个指向空结尾的字串的指针
  • P 一个指向定长字串的指针
  • q 一个有符号四倍(64位整数)值
  • Q 一个无符号四倍(64位整数)值
  • s 一个有符号短整数值,总是 16 位
  • S 一个无符号短整数值,总是 16 位,字节序跟机器芯片有关
  • u 一个无编码的字串
  • U 一个 Unicode 字符数字
  • v 一个“VAX”字节序(小头在前)的 16 位短整数
  • V 一个“VAX”字节序(小头在前)的 32 位短整数
  • w 一个 BER 压缩的整数
  • x 一个空字节(向前忽略一个字节)
  • X 备份一个字节
  • Z 一个空结束的(和空填充的)字节串
  • @ 用空字节填充绝对位置

一些规则:

1.每个字母后面都可以跟着一个数字,表示 count(计数),如果 count 是一个 * 表示剩下的所有东西。
2.如果你提供的参数比 $format 要求的少,pack 假设缺的都是空值。如果你提供的参数比 $format 要求的多,那么多余的参数被忽略。

echo pack('c', 65); //A
echo pack('c', 65, 97); //A 但是会报错, 因为多了一个参数
echo pack('c2', 65, 97);// Aa
echo pack('c*', 65, 97, 59, 97, 65); // Aa;aA *就是来多少填充多少..

冻结和解冻的PHP对象

之前无意间看到了 Freezing and Thawing PHP Objects 这篇文章翻译过来就是 冻结和解冻的PHP对象 感觉挺新鲜的, 然后花了点时间研究了下。

代码如下:

getProperties() as $attr) {

            $attr->setAccessible(true); //设置属性为访问级别public
            //ReflectionProperty::getName() 获取属性名
            //ReflectionProperty::getValue() 获取属性的值
            $state[$attr->getName()] = $attr->getValue($object) + 1;
        }
        return array('className' => get_class($object), 'state' => $state);
    }

    //解冻
    public static function thaw(array $frozenObject) {
        if(!class_exists($frozenObject['className'])) {
            throw new RuntimeException(sprintf('Class "%s could not be found"', $frozenObject['className']));
        }

        $object = unserialize(sprintf('O:%d:"%s":0:{}', strlen($frozenObject['className']), $frozenObject['className']));
        $reflector = new ReflectionObject($object);

        foreach ($frozenObject['state'] as $name => $value) {
            $attr = $reflector->getProperty($name);
            $attr->setAccessible(true);
            $attr->setValue($object, $value);
        }
        return $object;
    }
}

class Foo {

    public $a;
    protected $b;
    private $c;

    public function __construct($a, $b, $c) {
        $this->a = $a;
        $this->b = $b;
        $this->c = $c;
    }
}
$object = new Foo(1, 2, 3);
var_dump($object);
/* 输出结果
object(Foo)[1]
  public 'a' => int 1
  protected 'b' => int 2
  private 'c' => int 3
*/

$frozenObject =  ObjectFreezer::freeze($object);
var_dump($frozenObject);
/* 输出结果
array
  'className' => string 'Foo' (length=3)
  'state' =>
    array
      'a' => int 2
      'b' => int 3
      'c' => int 4
*/

$object = ObjectFreezer::thaw($frozenObject);
var_dump($object);
/* 输出结果
object(Foo)[5]
  public 'a' => int 2
  protected 'b' => int 3
  private 'c' => int 4
*/
?>

第一次就是输出了 $object 的所有字段信息

第二次经过调用 ObjectFreezer::freeze($object); 也就是冻结 $object 对象返回了一个数组

className没啥说的 $object 的类名

state是经过冻结后的 $object 对象的属性这里给他每个值加1

第三次通过 ObjectFreezer::thaw($frozenObject); 也就是解冻,返回了一个对象

可以看到这个对象中的属性值已经改变了.

这就是所谓的冻结与解冻php对象. 但是具体用到哪, 暂时还我也不清楚, 相信以后总有地方会用到.. ^_^

对了setAccessible是5.3才有的哦..

在看完 Freezing and Thawing PHP Objects 萌生了个想法, 使用php自带的serialize/unserialize这两个函数也许也能实现这样的功能啊..

然后动手试了下, 果然如此.

a = $a;
        $this->b = $b;
        $this->c = $c;
    }

    function show() {
        echo sprintf('$a=%d, $b=%d, $c=%d', $this->a, $this->b, $this->c);
    }

}
?>

注意一下字段的修饰符

show();
$string = serialize($foo);
$foo    = unserialize(str_replace(2, 20, $string)); //这里吧 $foo->b的值替换为20
//这里因为序列化后 protected和private字段 的表示方法不一样, 所以就好用替换了.. - -
$foo->show();
?>

输出结果
$a=1, $b=2, $c=3
$a=1, $b=20, $c=3

很明显, 这里也修改成功了..

PHP还提供了实现类似映射的一些函数

class_ exists
get_ called_ class
get_ class_ methods
get_ class_ vars
get_ class
get_ declared_ classes
get_ declared_ interfaces
get_ object_ vars
get_ parent_ class
interface_ exists
method_ exists
property_ exists

感叹下PHP真TMD强大..

牛X的PHP(用于坚定信念)

1.序言
定义:PHP是一种简单的,面向对象的,解释型的,健壮的,安全的,性能非常之高的,独立于架构的,可移植的,动态的脚本语言。PHP具有和JAVA类似的Class关键字。因为不需要虚拟机,以致速度比JAVA快5倍。PHP正迅速变成一种标准的,多用途的,面向对象的脚本语言。PHP不仅可用来开发Web应用程序,也可以开发普通应用程序。

PHP是一种功能强大的脚本语言。PHP将击败PERL/Python并取而代之。PHP是下一代的PERL/Python脚本。PHP可以胜任任何PERL/Python做的工作,并且做的更多,更好,更简洁!!

PHP是Hypertext Pre-Processor(超文本预处理器)的缩写,它是一种服务器端的HTML脚本/编程语言。PHP语法上与C相似,可运行在Apache, Netscape/iPlanet, 和 Microsoft IIS Web 服务器上。PHP作为一种工具,可以让你创建动态的Web页面。应用PHP的网页与常规的HTML页面并无二致,你可以用同样的方式来创建、编辑它们。PHP允许你直接在HTML文件里写入简单的脚本,这一点与Javas cript非常相似。而不同的是,PHP不依赖于浏览器,是服务器端的语言,而Javas cript却是一种客户端的嵌在HTML中的语言。概念上,PHP与Netscape的LiveWire Pro产品,Microsoft的ASP以及SunMicrosystem 的JSP相似。

PHP不仅可以用来创建Web应用程序,也可以用来开发普通的单机应用程序。

PHP的强劲之处在于:

·PHP是一项最优秀的技术。其它技术,如PERL,Python, Tcl, VB s cript, ASP 相对来说,都是陈旧低劣的。即使是Java/JSP,也在PHP之下。

·开放源码

·广泛的数据库连接

·大量的扩展库

·作为一种多用途的脚本语言,比PERL,VB s cript, ASP, JSP都要优秀。

为什么选择PHP?因为PHP是最好的,原因如下:

·PERL“味道不好”,因为其程序不易阅读和维护,且不是面向对象的。把PERL忘了,转向PHP吧。PERL程序员将抛弃PERL,因为他们爱上了PHP! PHP实际上就是“现代版的PERL”,只是名称不同而已。

·Java 是面向对象的,但速度很慢。Java程序远行起来很慢,对它唯一的抱怨就是——“Java,真是慢的糟糕”。而且十分复杂(具有许多层,如JVM,JIT 等等)。这往往诱发问题。既然有了Linux,为什么还要Java呢?

·Python“不错”,但没有C语言中的括号和大括号,而这在vi编辑器中对*控代码非常有用。如果不能利用vi/emacs编辑器搜索括号/大括号的命令迅速*控代码,那么就好象断了手一样。PHP在技术上比Python更加先进。

·PHP是最好的,因为它面向对象,并且吸收了C/C++/Java/PERL的精华。PHP可以替代PERL,Python, Java, C, C++, awk, Unix shell 脚本,Visual Basic 和其它语言!!

PHP直接运行,而且是由C写成的。

·每一个电脑程序员都知道PHP是最好的,不信问一下你旁边的程序员。

·只有PHP才能称雄于21世纪、22世纪以及更远的将来。

·为什么我们认为PERL,Python和Java程序员会将归附PHP,这里有一个很重要的原因。

以前,世界上许多公司都把PHP当作是一个“高度机密,严格保密”的电脑程序语言,但是现在它已经变成最为著名的,在Web, Internet, E-commerce以及 B2B等诸多项目上应用最广泛的面向对象的脚本语言。即使是在今天,仍有许多竞争性(competing)公司把PHP当作是高度机密的东西,决不向外界(竞争对手)透露半点。

PHP将如同暴风雨一般席卷整个世界,IT工业将为之震惊。PHP的力量在于它是跨平台的,可以运行在任何地方。如Linux,Windows 95/98/NT/2000/XP, Solaris, HPUX 以及各种UNIX。PHP只需写一次,就可以配置在任何地方。PHP可以运行在Apache,Microsoft IIS等多种Web服务器上。

PHP比Java快5到20倍!!实际的比较测试显示,PHP的运行速度是Java3.7倍左右。PHP太容易使用了,你可以用它在非常短的时间里,非常迅速的开发出非常复杂的web,e-commerce和一般的单机应用程序。(在将来,PHP将会模仿Java大多数的功能,相信Java程序员也会喜欢上它。PHP将包含Java中的关键字,如class, extends,interface, implements, public,protected, private 等等等等。)

PHP具有面向对象特性,它吸收了Java, C++, PERL 和C的最优秀的部分。PHP可以说是所有脚本/编程语言中的宝石。不久,它就会成为全世界程序员的“麦加圣地”。PHP即可以运行在Window95/NT/2000/XP上,也可以运行在各种UNIX上。

我们将大吃一惊——PHP极有可能成为21世纪的电脑编程语言。

可以使用Zend Optimizer对PHP进行编译和优化,从而使它运行的更快。PHP4.0中已经集成了Zend Optimizer。 首先,你在开发、测试、除错过程中,用PHP脚本语言编写你的应用程序。一旦项目完成,你便可以用Zend编译器,将PHP文件编译成运行速度更快的可执行程序。

对于电子商务项目,你一般需要综合使用PHP(70%),HTML/DHTML/XML(25%)和5%的Javas cript(客户端验证)。

Simple cookie method

/**
 * simple cookie method
 *
 * @access  public
 * @param   string    $name
 * @param   mixed   $value  when $value=null the remove cookie
 * @param   integer $expire
 * @param   string  $path
 * @param   string  $domain
 * @return  mixed
 */
function cookie($name, $value = '', $expire = null, $path = null, $domain = null)
{
    if (empty($value)) {
        if (is_null($value)) {
            //remove cookie
            if (isset($_COOKIE[$name])) {
                setcookie($name, $value, time()-3600, $path, $domain);
                unset($_COOKIE[$name]);
                return true;
            }
        }
        //get cookie
        $value = isset($_COOKIE[$name]) ? $_COOKIE[$name] : null;
        return unserialize($value);
    }
    //set cookie
    $expire = is_null($expire) ? $expire : time() + $expire;
    $value  = serialize($value);
    return setcookie($name, $value, $expire, $path, $domain);
}

一段数据库备份代码

    $dbname = 'database';
    $sql  = '';
    //创建数据库
    $arr  = $db->QueryFirst("SHOW CREATE DATABASE {$dbname}");
    $sql .= "/* 创建数据库 {$dbname} */\r\n";
    $sql .= "DROP DATABASE IF EXISTS {$dbname};\r\n{$arr['1']};\r\n";
    $sql .= "USE {$dbname};\r\n";

    //创建表
    $tables = $db->select("SHOW TABLES", "Tables_in_{$dbname}");
    $tables = array_keys($tables);
    foreach ($tables as $table) {
        $arr  = $db->QueryFirst("SHOW CREATE TABLE {$table}");
        $sql .= "\r\n/* 创建表 {$dbname}.{$table} */\r\n";
        $sql .= "DROP TABLES IF EXISTS {$table};\r\n{$arr['1']};\r\n";

        //获取数据
        $res    = $db->Query("SELECT * FROM {$table}");
        $values = array();
        while ($row = $db->FetchArray($res, MYSQL_ASSOC)) {
            $values[] = '(\'' . join('\',\'', array_map('addslashes', $row)) . '\')';
        }
        $values = join(',', $values) . ';';
        if ($values != ';') {
            $sql .= "\r\n/* 插入数据 {$table} */";
            $sql .= "\r\nINSERT INTO {$table} VALUES {$values}\r\n";
        }
    }

单独使用Ckfinder

一般我们用ckfinder都是与ckeditor或者fckeditor一起使用. 但是有时候需要独立使用我们怎么办呢.跟着写一次下面的代码就能独立使用了ckfinder了
首先加载ckfinder.js文件
文中会出现__DIR__, 这个是指你的ckfinder的路径




生成缩略图函数

/**
 * 生成图片缩略图
 *
 * @param   string  $src        原图地址
 * @param   string  $savePath   缩略图保存路径
 * @param   integer $width      缩略图宽
 * @param   integer $height     缩略图高
 * @return  true
 */
function buildThumb($src, $savePath, $width = 220, $height = 180)
{
    $arr = getimagesize($src);

    if (!is_array($arr)) {
        return false;
    }

    //1,2,3分别为gif,jpg,png
    if ($arr['2'] > 4) {
        return false;
    }

    $func = 'imagecreatefrom';
    switch ($arr['2']) {
        case 1  : $func .= 'gif'; break;
        case 2  : $func .= 'jpeg'; break;
        case 3  : $func .= 'png'; break;
        default :  $func .= 'jpeg';
    }

    $srcIm = $func($src);
    $im    = imagecreatetruecolor($width, $height);
    imagecopyresized($im, $srcIm, 0, 0, 0, 0, $width, $height, $arr['0'], $arr['1']);
    imagejpeg($im, $savePath);
    imagedestroy($srcIm);
    imagedestroy($im);
    return true;
}

使用方法

buildThumb('./src.jpg', './thumb.jpg', 100, 50);