Xiaopei's DokuWiki

These are the good times in your life,
so put on a smile and it'll be alright

User Tools

Site Tools


it:php

PHP

CI Codeigniter

  • CI 不支持命名空间 namespace
  • CI 可用的 http 库为 rmccue/Requests,star 多有维护的就它没用 namespace 了

composer

laravel 4.2 自动生成的 composer.json + phpunit 的依赖:

{
	"name": "laravel/laravel",
	"description": "The Laravel Framework.",
	"keywords": ["framework", "laravel"],
	"license": "MIT",
	"type": "project",
	"require": {
		"laravel/framework": "4.2.*"
	},
	"require-dev": {
		"phpunit/phpunit": "4.0.*"
	},
	"autoload": {
		"classmap": [
			"app/commands",
			"app/controllers",
			"app/models",
			"app/database/migrations",
			"app/database/seeds",
			"app/tests/TestCase.php"
		]
	},
	"scripts": {
		"post-install-cmd": [
			"php artisan clear-compiled",
			"php artisan optimize"
		],
		"post-update-cmd": [
			"php artisan clear-compiled",
			"php artisan optimize"
		],
		"post-create-project-cmd": [
			"php artisan key:generate"
		]
	},
	"config": {
		"preferred-install": "dist"
	},
	"minimum-stability": "stable"
}

tips

php 的 mysql 应该装 mysqlnd (native driver),否则会产生数据类型不对等问题

补充:

  • 最好再加上以下配置,以 laravel 为例:
    'mysql' => array(
        'driver'    => 'mysql',
        'host'      => 'localhost',
        'database'  => 'forge',
        'username'  => 'forge',
        'password'  => '',
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
        'options'   => array(
            PDO::ATTR_EMULATE_PREPARES => false,
            PDO::ATTR_STRINGIFY_FETCHES => false
        )
    ),

再补充:

  • 几种 exec 方法的对比
     // exec — Execute an external program
     // - 返回值为运行结果的最后一行;
     // - 要获得全部结果, 需使用 $output 参数;
     // - 要获得返回码, 需使用 $return_var 参数;
     string exec ( string $command [, array &$output [, int &$return_var ]] )
     
     // shell_exec — Execute command via shell and return the complete output as a string
     string shell_exec ( string $cmd )
     
     // 以下两种方法会直接打印 $command 的输出
     // passthru — Execute an external program and display raw output
     void passthru ( string $command [, int &$return_var ] )
     // system — Execute an external program and display the output
     string system ( string $command [, int &$return_var ] )
     // If you need to execute a command and have all the data from the command passed directly back without any interference, use the passthru() function. 
     
     // pcntl_exec — 在当前进程空间执行指定程序
     void pcntl_exec ( string $path [, array $args [, array $envs ]] )

lua

php 的 lua 库有:

  1. phplua - LUA for PHP, 有 compile 方法, 在 eval lua 前可用 compile 检查语法错误(适合用来保存用户输入的 lua 脚本)

phplua 需要自己编译, 编译步骤如下:

  1. 安装依赖, phplua(至少到 0.2.3) 使用 liblua5.1, aptitude install liblua5.1-0 liblua5.1-0-dev
  2. 下载最新版 phplua, 解压
  3. phpize, ./configure, make, make install
  4. 如果 make 时提示找不到 lua 的错误(ld: cannot find -llua) , 可能是库中有版本号而不识别的问题:
    cd /usr/lib/x86_64-linux-gnu
    ln -s liblua5.1.so liblua.so
    ldconfig
    # 重新 ./configure

5.4

升级 PHP 5.4 后, 若遇到 pecl 安装依赖仍要安在 20090626 里, 则可能是 php5-dev 和 php-pear 未升级到 5.4.

dpkg -l | grep php | grep -v 5.4 检查一下, 都升 5.4.

xdebug

  1. 安装 xdebug 可让 php 的出错信息更完整(aptitude install php5-xdebug)
  2. xdebug 会影响到 php.ini 配置的各处记录的出错信息
    1. log_errors + error_log 在日志中记录
    2. display_errors + html_errors 在 web 页面中记录

xdebug 的 profiler 功能可用来查看 php 运行中各步骤的效率, profiler 可用 webgrind 查看.

各服务器下设置 php 上传尺寸限制

  • php.ini
    ; Maximum allowed size for uploaded files.
    upload_max_filesize = 40M
    
    ; Must be greater than or equal to upload_max_filesize
    post_max_size = 40M
  • nginx
    http {
    	#...
            client_max_body_size 100m;
    	#...
    }

magic methods

__call()

一种 decorator 的写法

<?php
class Foo {
 
  function a() {
    echo "hello\n";
  }
 
  static function x() {
    echo "begin\n";
  }
 
}
 
class Bar extends Foo {
 
  function __construct() {
    $this->foo = new Foo();
  }
 
  function b() {
    echo "goodbye\n";
  }
 
  static function y() {
    echo "end\n";
  }
 
  //  __call() is triggered when invoking **INACCESSIBLE** methods in an object context.
  public function __call($name, $arguments) {
    // Note: value of $name is case sensitive.
    echo "Calling object method '$name' "
      . implode(', ', $arguments). "\n";
 
    if ( method_exists($this->foo, $name) ) {
      echo "foo has this method\n";
      return call_user_func_array(array($this->foo, $name), $arguments);
    }
    else {
      throw new Exception;
    }
  }
 
  // __callStatic() is triggered when invoking **INACCESSIBLE** methods in a static context.
  public static function __callStatic($name, $arguments) {
    // Note: value of $name is case sensitive.
    echo "Calling static method '$name' "
      . implode(', ', $arguments). "\n";
 
    $foo_class = get_class($this->foo);
    if ( method_exists($foo_class, $name) ) {
      return call_user_func_array(array($foo_class, $name), $arguments);
    }
    else {
      throw new Exception;
    }
 
  }
 
}
 
$bar = new Bar;
 
$bar->a();
$bar->b();
 
Bar::x();
Bar::y();

fopen

$handle = @fopen("/tmp/inputfile.txt", "r");
if ($handle) {
    while (($buffer = fgets($handle, 4096)) !== false) {
        echo $buffer;
    }
    if (!feof($handle)) {
        echo "Error: unexpected fgets() fail\n";
    }
    fclose($handle);
}

PHP-FPM - A simple and robust FastCGI Process Manager for PHP

pm = dynamic

dynamic - the number of child processes are set dynamically based on the
        following directives. With this process management, there will be
        always at least 1 children.
        pm.max_children      - the maximum number of children that can
                               be alive at the same time.
        pm.start_servers     - the number of children created on startup.
        pm.min_spare_servers - the minimum number of children in 'idle'
                               state (waiting to process). If the number
                               of 'idle' processes is less than this
                               number then some children will be created.
        pm.max_spare_servers - the maximum number of children in 'idle'
                               state (waiting to process). If the number
                               of 'idle' processes is greater than this
                               number then some children will be killed.,
  • pm.max_children: 最多子进程数
  • pm.start_servers: 初始进程数
  • pm.min_spare_servers, pm.max_spare_servers: spare server(idle process), 即未在处理请求的空闲进程, fpm 会在少于 min_spare_servers 个进程时不断创建进程, 多于 max_spare_servers 时不断 kill 进程

mpm_common - Apache HTTP Server , php-fpm 配置中的一些概念来自 apache mpm, 所以在 php-fpm 中解释不清楚的配置(min/max spare servers), 可参考 apache 的文档

listen 配置

# socket
listen = /var/run/php5-fpm/DOMAINNAME.socket
listen.owner = nginx
listen.group = www-data
listen.mode=0660

# port
listen = 127.0.0.1:9000

listen.backlog = -1


; Unix user/group of processes
user = (THE USERNAME OF THE USER THAT OWNS THE SITE FILES)
group = www-data

其他有用配置

 ; 服务若干请求后进程重启, 可减轻不当的程序造成的内存泄露问题
 ; This can be useful to work around memory leaks in 3rd party libraries. For
 ; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
 ; Default Value: 0
 pm.max_requests = 500

oauth

通过 pecl 可安装 php 的 oauth 1 库 1):

$ aptitude install php-pear php5-dev build-essential libpcre3-dev
$ pecl install oauth

strtotime

  • Calculating start and end dates of a week
    $year = $form['year'] ? : date('Y', Date::time());
    $week = $form['week'] ? : date('W', Date::time());
    $week = min(max(floor($week), 1), 53);		// week 应为 1~53 的整数
    $week = str_pad($week, 2, 0, STR_PAD_LEFT);	// week 1~9 应补足 2 位
     
    $week_start = strtotime("{$year}-W{$week}-1");
    $week_end = strtotime("{$year}-W{$week}-7") + 86400;
     
    // * 每周以周一开始
    // * 一年的 W53 可能与第二年的 W01 相同
    // http://en.wikipedia.org/wiki/ISO_8601#Week_dates

OO

static:: Late Static Bindings

PHP: Late Static Bindings - Manual

Here statically accessed property prefer property of the class for which it is called. Where as self keyword enforces use of current class only. Refer the below example:

<?php
class a{
 
    static protected $test="class a";
 
    public function static_test(){
 
        echo static::$test; // Results class b
        echo self::$test; // Results class a
 
    }
 
}
 
class b extends a{
 
    static protected $test="class b";
 
}
 
$obj = new b();
$obj->static_test();
?>

PDO

// Connection management
try {
    $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
    foreach($dbh->query('SELECT * from FOO') as $row) {
        print_r($row);
    }
    $dbh = null;
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

filter_var()

验证 email, URL 等常见格式, 应该用 filter_var(), 不用自己写正则表达式

已知问题

curl

  • 问题: 某 php 程序中使用了到 example.com 的 curl, 服务器直接访问 example.com 速度快, 但访问此 php 时, 速度慢
  • 原因: php curl 与 linux 自身 nslookup 可能不同
  • 发现过程:
    1. 默认情况下, ping example.com 快, web 访问慢;
    2. 在 /etc/hosts 增加 example.com 的记录, ping example.com 快, web 访问快;
    3. stackoverflow 中有人提出类似问题: PHP/curl: namelookup_time/dns slowing requests - Stack Overflow
    4. 从日志进一步确认以上问题与当前情况相同:
      genee@brandy:~$ tailf /var/log/php5/cgi.log 
      [19-Sep-2012 02:07:24 UTC] CURL INFO: Array
      (
          [url] => http://example.com/tncic/api
          [content_type] => text/html
          [http_code] => 200
          [header_size] => 381
          [request_size] => 277
          [filetime] => -1
          [ssl_verify_result] => 0
          [redirect_count] => 0
          [total_time] => 2.884
          [namelookup_time] => 2.77733
          [connect_time] => 2.777412
          [pretransfer_time] => 2.777414
          [size_upload] => 76
          [size_download] => 30
          [speed_download] => 10
          [speed_upload] => 26
          [download_content_length] => -1
          [upload_content_length] => 76
          [starttransfer_time] => 2.883948
          [redirect_time] => 0
          [certinfo] => Array
              (
              )
      
          [redirect_url] => 
      )
  • 解决方法: /etc/hosts 增加记录解决

error_log() 不分时区, 总是使用 UTC(Coordinated Universal Time)

php-oci8

  1. sudo pecl install oci82)

flock()

flock

$mutex_file = Config::get('system.tmp_dir') . 'order_mo';  // mutex n. 互斥
 
// $mutex_file = Config::get('system.tmp_dir') . Misc::key('order_no');
// Misc::key() 会对传入参数做 md4 处理
 
File::check_path($mutex_file);
 
$fp = fopen($mutex_file, 'w+');
 
// error_log($this->customer->id . ' is coming');
 
// 1. 阻塞式 flock(), 堵塞的话 flock() 会自动等待 (xiaopei.li@2012-07-02)
if (!flock($fp, LOCK_EX)) {
	return FALSE;
}
/*
  正常日志应例如
  [02-Jul-2012 06:10:53 UTC] 2 is coming
  [02-Jul-2012 06:10:53 UTC] 2 get lock
  [02-Jul-2012 06:10:55 UTC] 1 is coming
  [02-Jul-2012 06:11:03 UTC] 2 release lock
  [02-Jul-2012 06:11:03 UTC] 1 get lock
  [02-Jul-2012 06:11:13 UTC] 1 release lock
*/
// end 1
 
// 2. 如果不希望 flock() 在锁定时堵塞,则需加 LOCK_NB,
//    加 LOCK_NB( NO BLOCK ) 后需**手动**设置等待机制 (xiaopei.li@2012-07-02)
/*
  $tried_left = 20;
  while (!flock($fp, LOCK_EX | LOCK_NB)) {  // acquire an exclusive lock
 
  error_log($this->customer->id . ' is wating');
 
  sleep(1);
 
  if (!$tried_left--) {
  return FALSE;
  }
  }
*/
/*
  正常日志应例如
  [02-Jul-2012 06:01:12 UTC] 2 is coming
  [02-Jul-2012 06:01:12 UTC] 2 get lock
  [02-Jul-2012 06:01:13 UTC] 1 is coming
  [02-Jul-2012 06:01:13 UTC] 1 is wating
  [02-Jul-2012 06:01:14 UTC] 1 is wating
  [02-Jul-2012 06:01:15 UTC] 1 is wating
  [02-Jul-2012 06:01:16 UTC] 1 is wating
  [02-Jul-2012 06:01:17 UTC] 1 is wating
  [02-Jul-2012 06:01:18 UTC] 1 is wating
  [02-Jul-2012 06:01:19 UTC] 1 is wating
  [02-Jul-2012 06:01:20 UTC] 1 is wating
  [02-Jul-2012 06:01:21 UTC] 1 is wating
  [02-Jul-2012 06:01:22 UTC] 2 release lock
  [02-Jul-2012 06:01:22 UTC] 1 get lock
  [02-Jul-2012 06:01:32 UTC] 1 release lock
*/
// end 2
 
 
// error_log($this->customer->id . ' get lock');
// sleep(10);
 
$today_order_count = O('order_count', array(
			'year' => $year,
			'month' => $month,
			'day' => $day,
			));
 
if (!$today_order_count->id) {
	$today_order_count->year = $year;
	$today_order_count->month = $month;
	$today_order_count->day = $day;
	$today_order_count->count = 0;
}
 
$count = $today_order_count->count + 1;
 
// order_no 支持以下符号
// %y - year, 如 12
// %m - month, 如 05
// %d - day of month, 如 31
// %c - order count of day, 3位, 如当天第 10 个订单为 010
$template = Config::get('order.order_no_template') ? : '%y%m%d%c';
$this->order_no = T($template, array(
			'%y' => $year,
			'%m' => $month,
			'%d' => $day,
			'%c' => Number::fill($count, 3),
			// TODO 对 %c 的读/写需要加锁! 否则可能造成混乱(xiaopei.li@2012-05-31)
			));
 
$ret = parent::save();
 
if ($ret) {
	$today_order_count->count = $count;
	$today_order_count->save();
}
 
flock($fp, LOCK_UN); // release the lock
 
// error_log($this->customer->id . ' release lock');
 
fclose($fp);

PCRE - Perl Compatible Regular Expressions

cli

从 cgi 中调用 cli

只要脚本符合 1. 无输出 2.后台运行, 就能让主进程继续:

echo 'hello';
 
$cmd = 'foo > /dev/null 2>&1 &';
exec($cmd);
 
echo 'goodbye';

以前另一种方法如下, 但好像不 work, 详见 close a connection early:

function some_controller() {
	// 先关闭 http 连接
	$this->_close_connection_and_go_on();
 
	// 再进行耗时的工作
 
}
 
function _close_connection_and_go_on($output) {
	ob_end_clean();
	header("Connection: close\r\n");
	header("Content-Encoding: none\r\n");
	ignore_user_abort(true); // optional
	ob_start();
	print $output;
	$size = ob_get_length();
	header("Content-Length: $size");
	ob_end_flush();     // Strange behaviour, will not work
	flush();            // Unless both are called !
	ob_end_clean();
	/* 参考:http://www.php.net/manual/en/features.connection-handling.php */
 
	sleep(10);
}

getopt()

从命令行读取指定参数.

// 函数描述:
// array getopt ( string $options [, array $longopts ] )
 
// php 例程:
$shortopts = "v:md";
$longopts = array(
	'vendor:',
	'merge',
	'dry',
	);
 
$options = getopt($shortopts, $longopts);
var_dump($options)
 
// 测试 1:
// $ foo.php -v 1 -m -d
array(3) {
  ["v"]=>
  string(1) "1"
  ["m"]=>
  bool(false)
  ["d"]=>
  bool(false)
}
 
// 测试 2:
// $ foo.php --vendor 1 --merge --dry
array(3) {
  ["vendor"]=>
  string(1) "1"
  ["merge"]=>
  bool(false)
  ["dry"]=>
  bool(false)
}

参数后:

  • 无冒号, 说明此参数不能带值
  • 一个冒号, 说明此参数必须有值
  • 两个冒号, 说明此参数有无值都可

an example from the cookbook

这个例子有些老了, 读, 改 FIXME

// Load the readline library
if (! function_exists('readline')) {
    dl('readline.'. (((strtoupper(substr(PHP_OS,0,3))) == 'WIN')?'dll':'so'))
        or die("Readline library required\n");
}
 
// Load the Console_Getopt class
require 'Console/Getopt.php';
 
$o = new Console_Getopt;
$opts = $o->getopt($o->readPHPArgv(),'hm',array('help','multiline'));
 
// Quit with a usage message if the arguments are bad
if (PEAR::isError($opts)) {
    print $opts->getMessage();
    print "\n";
    usage();
}
 
// Default is to evaluate each command as it's entered
$multiline = false;
 
foreach ($opts[0] as $opt) {
    // Remove any leading -s
    $opt[0] = preg_replace('/^-+/','',$opt[0]);
 
    // Check the first character of the argument
    switch($opt[0][0]) {
    case 'h':
        // display help
        usage();
        break;
    case 'm':
        $multiline = true;
        break;
    }
}
 
// Set up error display
ini_set('display_errors',false);
ini_set('log_errors',true);
 
// Build readline completion table
$functions = get_defined_functions();
foreach ($functions['internal'] as $k => $v) {
    $functions['internal'][$k] = "$v(";
}
function function_list($line) {
    return $GLOBALS['functions']['internal'];
}
readline_completion_function('function_list');
 
$cmd = '';
$cmd_count = 1;
 
while (true) {
    // Get a line of input from the user
    $s = readline("[$cmd_count]> ");
    // Add it to the command history
    readline_add_history($s);
    // If we're in multiline mode:
    if ($multiline) {
        // if just a "." has been entered
        if ('.' == rtrim($s)) {
            // eval() the code
            eval($cmd);
            // Clear out the accumulated code
            $cmd = '';
            // Increment the command count
            $cmd_count++;
            // Start the next prompt on a new line
            print "\n";
        } else {
            /* Otherwise, add the new line to the accumulated code
               tacking on a newline prevents //-style comments from
               commenting out the rest of the lines entered
            */
            $cmd .= $s."\n";;
        }
    } else {
        // If we're not in multiline mode, eval() the line
        eval($s);
        // Increment the command count
        $cmd_count++;
        // Start the next prompt in a new line
        print "\n";
    }
}
 
// Display helpful usage information
function usage() {
    $my_name = $argv[0];
 
    print<<<_USAGE_
Usage: $my_name [-h|--help] [-m|--multiline]
 
  -h, --help: display this help
  -m, --multiline: execute accumulated code when "." is entered
                   by itself on a line. The default is to execute
                   each line after it is entered.    
 
_USAGE_;
    exit(-1);
}

syslog

bool syslog ( int $priority , string $message )

syslog() 可以和 openlog()/closelog() 一起使用, 但这样比较麻烦. 实际上 openlog() will automatically be called by syslog() if necessary, syslog() 的 priority is a combination of the facility and the level, 但是 in which case ident will default to FALSE. 结合上述优缺点, 较好的调用 syslog 方法如下:

<?php
$ident = 'subsystem1';
syslog(LOG_NOTICE | LOG_LOCAL1, $ident.' '.$message);
?>

各 priority 值为下:

LOG_EMERG0
LOG_ALERT1
LOG_CRIT2
LOG_ERR3
LOG_WARNING4
LOG_NOTICE5
LOG_INFO6
LOG_DEBUG7

http://www.php.net/manual/en/function.openlog.php#98307

yaf - yet another framework

安装

# 应先安装以下支持, 避免报错 pcre.h: No such file or directory
$ sudo apt-get install libpcre3-dev
 
$ pecl install yaf
# You should add "extension=yaf.so" to php.ini

PEAR & PECL

PEAR is PHP Extension and Application Repository, it has libraries and code written IN php. Those you can simply download, install and include in your code.

PECL stands for PHP Extension Community Library, it has extensions written in C, that can be loaded into PHP to provide additional functionality. You need to have administrator rights, a C compiler and associated toolchain to install those extensions.

http://stackoverflow.com/questions/1385346/what-are-differences-between-pecl-and-pear

安装 PEAR & PECL

$ sudo apt-get install php5 php5-cli php-pear

使用 PEAR

  1. 列出频道 (Channel) 清单
    $ pear list-channels
    Registered Channels:
    ====================
    Channel      Alias   Summary
    doc.php.net  phpdocs PHP Documentation Team
    pear.php.net pear    PHP Extension and Application
                         Repository
    pecl.php.net pecl    PHP Extension Community Library
    __uri        __uri   Pseudo-channel for static packages
  2. 列出频道的信息
    $ pear channel-info pear.php.net
    Channel pear.php.net Information:
    =================================
    Name and Server         pear.php.net
    Alias                   pear
    Summary                 PHP Extension and Application Repository
    Validation Package Name PEAR_Validate
    Validation Package      default
    ()
  3. 新增频道 (Channel)
    $ pear channel-discover pear.phpunit.de # phpunit 在此频道
  4. 更新频道 (Channel)
    # 更新某频道
    $ pear channel-update pear.phpunit.de
    # 更新所有频道
    $ pear update-channels
  5. 移除频道(Channel)
    $ pear channel-delete pear.phpunit.de
  6. 列出已安装的套件清单
    $ pear list
  7. 搜寻可安装的套件清单
    $ pear search [套件的关键字]
  8. 安装套件
    $ pear install [套件名称]
  9. 安装指定版本的套件
    # 先列出所有 phpunit 的套件
    $ pear remote-list -c phpunit
     
    # 接着,再从清单中选择特定版本安装:
    $ pear install phpunit/package_name-1.0.0  # 安装 1.0.0 的版本
    $ pear install phpunit/package_name-beta   # 安装 beta 的版本
  10. 升级套件
    # 查询可升级的清单列表
    $ pear list-upgrades
     
    # 升级某个
    $ pear upgrade [套件名称]
     
    # 升级所有
    $ pear upgrade-all
  11. 移除套件
    $ pear uninstall [套件名称]

使用 PECL

与 PEAR 类似。

PEAR2

PHP 官方目前希望逐步以 PEAR2(第二代的 Pear)来取代旧有的 PEAR,未来将以 pyrus 指令替换原本使用的 pear。第二代的设计上採用 “Phar”(类似于 Java 的 jar)的方式来包装与管理扩展模块。

以上参考自: PHP extension management tools - Pecl and Pear

MVC

一些 MVC 的学习笔记:

CGI

Common_Gateway_Interface

The Common Gateway Interface (CGI) is a standard (see RFC 3875: CGI Version 1.1) method for web server software to delegate the generation of web pages to executable files. Such files are known as CGI scripts; they are programs, often stand-alone applications, usually written in a scripting language.

Environment variables passed to a CGI program

  • Server specific variables:
    • SERVER_SOFTWARE — name/version of HTTP server.
    • SERVER_NAME — host name of the server, may be dot-decimal IP address.
    • GATEWAY_INTERFACE — CGI/version.
  • Request specific variables:
    • SERVER_PROTOCOL — HTTP/version.
    • SERVER_PORT — TCP port (decimal).
    • REQUEST_METHOD — name of HTTP method (see above).
    • PATH_INFO — path suffix, if appended to URL after program name and a slash.
    • PATH_TRANSLATED — corresponding full path as supposed by server, if PATH_INFO is present.
    • SCRIPT_NAME — relative path to the program, like /cgi-bin/script.cgi.
    • QUERY_STRING — the part of URL after ? character. May be composed of *name=value pairs separated with ampersands (such as var1=val1&var2=val2…) when used to submit form data transferred via GET method as defined by HTML application/x-www-form-urlencoded.
    • REMOTE_HOST — host name of the client, unset if server did not perform such lookup.
    • REMOTE_ADDR — IP address of the client (dot-decimal).
    • AUTH_TYPE — identification type, if applicable.
    • REMOTE_USER used for certain AUTH_TYPEs.
    • REMOTE_IDENT — see ident, only if server performed such lookup.
    • CONTENT_TYPE — MIME type of input data if PUT or POST method are used, as provided via HTTP header.
    • CONTENT_LENGTH — similarly, size of input data (decimal, in octets) if provided via HTTP header.
    • Variables passed by user agent (HTTP_ACCEPT, HTTP_ACCEPT_LANGUAGE, HTTP_USER_AGENT, HTTP_COOKIE and possibly others) contain values of corresponding HTTP headers and therefore have the same sense.

Output format

The program returns the result to the web server in the form of standard output, beginning with a header and a blank line.

The header is encoded in the same way as an HTTP header and must include the MIME type of the document returned. The headers, supplemented by the web server, are generally forwarded with the response back to the user.

be/le, 32/64 等问题

字节序, wp>字节序

php二进制字符串与其他类型互相转换的 pack/unpack 方法

32位中无符号整数错误导致的原因是 php 内部无论整数有无符号, 都用有符号型保存

而处理方法(有简单有复杂)可用 sprintf('%u', $x): http://www.php.net/manual/en/function.unpack.php#106041

http://cn2.php.net/manual/en/function.header.php

Example #1 Download dialog

<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');
 
// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');
 
// The PDF source is in original.pdf
readfile('original.pdf');
?> 

Example #2 Caching directives

<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
?>

Phar

如果要开启打包功能, 需修改 cli/php.ini 设置 phar.readonly = Off

http://www.jaceju.net/blog/archives/344/

解开 phar

extract.php
<?php
$p = new Phar('/home/genee/system.phar.xue');
$p->extractTo('/home/genee/sysphar.xue'); // extract all files

常见打包故障

  • 混淆:
    $my_method = 'some_method';
    self::$my_method($my_var);
    # 以上写法在打包混淆变量时, 可能造成无法调用
    
    call_user_func(array(self, $my_method), $my_var);
     
    compact()
it/php.txt · Last modified: 2016/02/17 20:08 by admin