友链
导航
These are the good times in your life,
so put on a smile and it'll be alright
友链
导航
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" }
php 的 mysql 应该装 mysqlnd (native driver),否则会产生数据类型不对等问题
补充:
'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 ) ),
再补充:
substr_compare($str, $test, -strlen($test), strlen($test)) === 0;
// 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 ]] )
php 的 lua 库有:
phplua 需要自己编译, 编译步骤如下:
aptitude install liblua5.1-0 liblua5.1-0-dev
phpize
, ./configure
, make
, make install
ld: cannot find -llua
) , 可能是库中有版本号而不识别的问题:cd /usr/lib/x86_64-linux-gnu ln -s liblua5.1.so liblua.so ldconfig # 重新 ./configure
升级 PHP 5.4 后, 若遇到 pecl 安装依赖仍要安在 20090626 里, 则可能是 php5-dev 和 php-pear 未升级到 5.4.
需 dpkg -l | grep php | grep -v 5.4
检查一下, 都升 5.4.
xdebug 的 profiler 功能可用来查看 php 运行中各步骤的效率, profiler 可用 webgrind 查看.
; Maximum allowed size for uploaded files. upload_max_filesize = 40M ; Must be greater than or equal to upload_max_filesize post_max_size = 40M
http { #... client_max_body_size 100m; #... }
一种 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();
$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); }
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.,
mpm_common - Apache HTTP Server , php-fpm 配置中的一些概念来自 apache mpm, 所以在 php-fpm 中解释不清楚的配置(min/max spare servers), 可参考 apache 的文档
# 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
通过 pecl 可安装 php 的 oauth 1 库 1):
$ aptitude install php-pear php5-dev build-essential libpcre3-dev $ pecl install oauth
$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
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(); ?>
// 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(); }
验证 email, URL 等常见格式, 应该用 filter_var(), 不用自己写正则表达式
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] => )
sudo pecl install oci8
2)$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);
只要脚本符合 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); }
从命令行读取指定参数.
// 函数描述: // 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) }
参数后:
这个例子有些老了, 读, 改
// 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); }
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_EMERG | 0 |
---|---|
LOG_ALERT | 1 |
LOG_CRIT | 2 |
LOG_ERR | 3 |
LOG_WARNING | 4 |
LOG_NOTICE | 5 |
LOG_INFO | 6 |
LOG_DEBUG | 7 |
# 应先安装以下支持, 避免报错 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 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
$ sudo apt-get install php5 php5-cli php-pear
$ 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
$ 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 (略)
$ pear channel-discover pear.phpunit.de # phpunit 在此频道
# 更新某频道 $ pear channel-update pear.phpunit.de # 更新所有频道 $ pear update-channels
$ pear channel-delete pear.phpunit.de
$ pear list
$ pear search [套件的关键字]
$ pear install [套件名称]
# 先列出所有 phpunit 的套件 $ pear remote-list -c phpunit # 接着,再从清单中选择特定版本安装: $ pear install phpunit/package_name-1.0.0 # 安装 1.0.0 的版本 $ pear install phpunit/package_name-beta # 安装 beta 的版本
# 查询可升级的清单列表 $ pear list-upgrades # 升级某个 $ pear upgrade [套件名称] # 升级所有 $ pear upgrade-all
$ pear uninstall [套件名称]
与 PEAR 类似。
PHP 官方目前希望逐步以 PEAR2(第二代的 Pear)来取代旧有的 PEAR,未来将以 pyrus 指令替换原本使用的 pear。第二代的设计上採用 “Phar”(类似于 Java 的 jar)的方式来包装与管理扩展模块。
一些 MVC 的学习笔记:
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.
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.
字节序, 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 ?>
如果要开启打包功能, 需修改 cli/php.ini
设置 phar.readonly = Off
<?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()