SegmentFault 风逐蓝天's Blog最新的文章
2016-09-22T18:22:14+08:00
https://segmentfault.com/feeds/blogs
https://creativecommons.org/licenses/by-nc-nd/4.0/
macOS 误删除 /private/var/folders 导致无法启动的解决方案
https://segmentfault.com/a/1190000006978510
2016-09-22T18:22:14+08:00
2016-09-22T18:22:14+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<h2>概述:</h2>
<p>启动进入命令行模式,挂载硬盘,创建目录,重启。</p>
<h2>步骤:</h2>
<p>1、关闭电脑,按住 Command+S 启动进入单人模式(single-user mode),进入命令行模式。</p>
<p>2、检查 root 文件系统</p>
<p><code>/sbin/fsck -fy</code></p>
<p>3、挂载 root 文件系统,需要读写权限<br><code>/sbin/mount -uw /</code></p>
<p>4、创建被删除的目录</p>
<p><code>mkdir /var/folders/zz</code><br>或者 <code>mkdir /var/folders</code> 并且 <code>mkdir /var/folders/zz</code></p>
<p>5、重启</p>
<p><code>reboot</code></p>
使用 gdb 调试 PHP core
https://segmentfault.com/a/1190000005168629
2016-05-20T21:05:04+08:00
2016-05-20T21:05:04+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
5
<h2>一、开启</h2>
<h4>查看是否开启 core dump 输出</h4>
<p>ulimit -a</p>
<h4>打开 core dump 文件记录</h4>
<p>ulimit -c unlimited</p>
<p>yum install gdb php-dbg</p>
<h4>关闭 core dump 文件记录</h4>
<p>ulimit -c 0</p>
<p>设置内核core dump出来的存放路径(注意目录要有权限给php写):<br>echo "/tmp/core.%e.%p.%t" > /proc/sys/kernel/core_pattern</p>
<h2>二、调试</h2>
<h4>1、准备 .gdbinit 文件</h4>
<p>获取地址:<a href="https://link.segmentfault.com/?enc=SqTwg9U6Tj0IDsS%2ByLzdtw%3D%3D.oVQrMBKkI6pVvdvbR06o%2B1KnNx5vQOuTbi2BAQQav3muH1cDHkaAFKuW5j6RA%2Fwy%2FkapiODrf0Xi1gvclgIAog%3D%3D" rel="nofollow">https://github.com/php/php-src/blob/master/.gdbinit</a><br>保存在服务器上,例如 <code>/root/.gdbinit</code> 备用。</p>
<h4>2、用 gdb 打开 core 文件</h4>
<p><code>gdb php-fpm -c core-php-fpm.920</code></p>
<p>可以看到类似下边的字样:</p>
<pre><code>Core was generated by `php-fpm: pool www '.
Program terminated with signal 11, Segmentation fault.</code></pre>
<h4>3、查看 core 发生时刻的堆栈</h4>
<pre><code>(gdb) bt
#0 zend_mm_alloc_small (size=<value optimized out>) at /usr/src/debug/php-7.0.6/Zend/zend_alloc.c:1295
#1 zend_mm_alloc_heap (size=<value optimized out>) at /usr/src/debug/php-7.0.6/Zend/zend_alloc.c:1366
#2 _emalloc (size=<value optimized out>) at /usr/src/debug/php-7.0.6/Zend/zend_alloc.c:2450
#3 0x00007f7a6fad0511 in apm_sprintf (fmt=0x7f7a6faeff50 "\n %04d-%02d-%02d %02d:%02d:%02d Version %s\n Process %d received signal %2d: %s , bss[%p]\n")
at /PHP/64/source/php7.0.0_nzts/ext/apm/apm_common.c:371
#4 0x00007f7a6facbefd in print_backtrace (sig=11) at /PHP/64/source/php7.0.0_nzts/ext/apm/apm.c:1937
#5 0x00007f7a6facbfd7 in agent_fatal_signal_handler (sig=11) at /PHP/64/source/php7.0.0_nzts/ext/apm/apm.c:1955
#6 <signal handler called>
#7 zend_mm_alloc_small (size=<value optimized out>) at /usr/src/debug/php-7.0.6/Zend/zend_alloc.c:1295
#8 zend_mm_alloc_heap (size=<value optimized out>) at /usr/src/debug/php-7.0.6/Zend/zend_alloc.c:1366</code></pre>
<h3>4、引入 PHP 源代码中提供的 .gdbinit (gdb 命令编写脚本)</h3>
<pre><code>(gdb) source /root/.gdbinit</code></pre>
<h4>5、查看 backtrace 和变量值</h4>
<pre><code>(gdb) zbacktrace
[0x7f7a75e138c0] C("DEBUG") /usr/share/nginx/html/smartphp/common.php:28
[0x7f7a75e137d0] Model->_connectDb() /usr/share/nginx/html/smartphp/core/Model.class.php:44
[0x7f7a75e13680] Model->bindData("SELECT\40tips\40FROM\40keyword_phone\40WHERE\40word=:word", array(1)[0x7f7a75e136f0], "getdata") /usr/share/nginx/html/smartphp/core/Model.class.php:143
[0x7f7a75e13580] Model->getData("SELECT\40tips\40FROM\40keyword_phone\40WHERE\40word=:word", array(1)[0x7f7a75e135f0]) /usr/share/nginx/html/smartphp/core/Model.class.php:215
[0x7f7a75e134c0] Model->getField("SELECT\40tips\40FROM\40keyword_phone\40WHERE\40word=:word", array(1)[0x7f7a75e13530]) /usr/share/nginx/html/appdata/smartphp/core/Model.class.php:264</code></pre>
<pre><code>(gdb) print ((zval *)0x7f7a75e13530)
$1 = (zval *) 0x7f7a75e13530
(gdb) printzv $1
[0x7f7a75e13530] (refcount=3) array: Packed(1)[0x7f7a75e94888]: {
[0] 0 => [0x7f7a75e6ad88] (refcount=4) string: PP红包。
}</code></pre>
<p><a href="https://link.segmentfault.com/?enc=ZUc4tkBwcvGYYTibLqRuUQ%3D%3D.RIV%2Bk7NJpzT87v7pH9lJi4J7Ma%2FfthLOyikVuafzPXcOYQYcpdCwXXDG%2F40HHYmkvpSLaQkFoszHqkMHJ9wa6g%3D%3D" rel="nofollow">https://bugs.php.net/bugs-generating-backtrace.php</a><br><a href="https://link.segmentfault.com/?enc=lY8lXH8mmFtEz7WovkHXLw%3D%3D.wc7sD79UwHzaSNumv45%2Bng%2F4UqOrXxRtn0iTWoXjXQ0Vk53rR%2Fo2%2B6z5GStZr8CD" rel="nofollow">http://www.laruence.com/2011/06/23/2057.html</a><br><a href="https://link.segmentfault.com/?enc=rkh9mbnmrh8PnxkI8GhH5Q%3D%3D.OKZGPUQ4nqywhzQUVSZLO4bZ3wIctHu247RTZvvpIG4T4fLHrW8TyVrIimG0CewDEl4K43s6oSeftCLv8JgMrA%3D%3D" rel="nofollow">https://kn007.net/topics/php-fpm-how-to-core-dump/</a><br><a href="https://link.segmentfault.com/?enc=zAxrkaNR9LdzK5XLTQlnGw%3D%3D.1uUFeq53MdoiELFRdQziHUAVG4kn%2BbNARuLYkI4zUQtKgvlvCnQ7flVAaU9wq9Nx" rel="nofollow">http://www.laruence.com/2011/12/06/2381.html</a></p>
Sublime Install Package 时出现 no packages available 的解决方案
https://segmentfault.com/a/1190000005145932
2016-05-18T01:06:43+08:00
2016-05-18T01:06:43+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<h2>现象:</h2>
<p>使用 <code>cmd + shift + p</code> (OS X) 打开 Package Control,选择 install,提示:<code>There are no packages available for installation。</code></p>
<h2>解决方法:</h2>
<p>关闭系统的 IPV6 功能。</p>
<p>OS X 下关闭方法:</p>
<pre><code>networksetup -setv6off Wi-Fi
networksetup -setv6off Ethernet(如果电脑有以太网接口)</code></pre>
<p>开启方法:</p>
<pre><code>networksetup -setv6automatic Wi-Fi
networksetup -setv6automatic Ethernet(如果电脑有以太网接口)</code></pre>
PHP 中 in_array 需要注意的一点
https://segmentfault.com/a/1190000005098985
2016-05-10T23:07:12+08:00
2016-05-10T23:07:12+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
1
<h2>示例</h2>
<p>先来看一个小示例:</p>
<pre><code>$needle = '1abc';
$haystack = array(1,2,3);
var_dump(in_array($needle, $haystack);
//输出为 true</code></pre>
<h2>解释</h2>
<p>根据官方文档函数 in_array 的描述:</p>
<pre><code>bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
在 haystack 中搜索 needle,如果没有设置 strict 则使用宽松的比较。</code></pre>
<p>第三个参数默认为 false,当 $needle 和 $haystack 中的元素比较时会进行类型转换,相当于使用 == 进行比较。</p>
<h2>总结</h2>
<p>in_array()第三个参数决定变量和数组中元素如何进行比较。值为 false(默认值)时,相当于 ==,值为 true 时,相当于 ===。</p>
Laravel 5 IDE Helper 安装
https://segmentfault.com/a/1190000004420099
2016-02-06T15:46:28+08:00
2016-02-06T15:46:28+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
7
<h2>一、项目地址</h2>
<p><a href="https://link.segmentfault.com/?enc=JukHSp0BP2%2FoBK5ngfvIaw%3D%3D.um2821wSDVuOfUnnv74x9bh9ezT8rTmTrVAk%2BHw3%2B8SeznNJPzUbslHUKALZm%2FLA" rel="nofollow">https://github.com/barryvdh/laravel-ide-helper</a></p>
<h2>二、安装方法</h2>
<h3>1、方法一:直接使用已经生成的文件</h3>
<p>下载 <a href="https://gist.github.com/barryvdh/5227822">https://gist.github.com/barryvdh/5227822</a> 中的 <code>_ide_helper.php</code>,放置于项目根目录。</p>
<h3>2、方法2:手动生成</h3>
<p>引入库:</p>
<pre><code>composer require barryvdh/laravel-ide-helper</code></pre>
<p>在 <code>config/app.php</code> 的 providers 中添加:</p>
<pre><code>Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,</code></pre>
<p>生成辅助文件:</p>
<pre><code>php artisan ide-helper:generate</code></pre>
<p>提示:需要首先清除 <code>bootstrap/compiled.php</code>,所以生成前需要执行 <code>php artisan clear-compiled</code>,生成后执行 <code>php artisan optimize</code>。</p>
<p>配置 composer.json 以在每次提交之后执行。</p>
<pre><code>"scripts":{
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan ide-helper:generate",
"php artisan optimize"
]
},</code></pre>
CentOS 6 搭建 FTP 服务记录
https://segmentfault.com/a/1190000002926477
2015-06-23T11:43:10+08:00
2015-06-23T11:43:10+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<h2>关于 VSFTP</h2>
<p>在 Linux 下搭建 FTP 服务器一般会使用 vsftpd。vsftpd 的前两个字母代表 "very secure" 。</p>
<p>项目官网:<a rel="nofollow" href="https://security.appspot.com/vsftpd.html">https://security.appspot.com/vsftpd.html</a></p>
<h2>安装 VSFTP</h2>
<p>使用 yum 安装 vsftpd:</p>
<pre><code>sudo yum install vsftpd
</code></pre>
<p>如果需要连接其他 FTP 服务器,则可以安装 FTP 客户端。</p>
<pre><code>sudo yum install ftp
</code></pre>
<h2>添加用户</h2>
<pre><code>adduser userftp
passwd userftp
</code></pre>
<p>禁止用户的 ssh 登录权限,只允许 FTP 访问:</p>
<pre><code>usermod -s /sbin/nologin userftp
</code></pre>
<h2>配置 VSFTP</h2>
<p>打开配置文件:</p>
<pre><code>sudo vi /etc/vsftpd/vsftpd.conf
</code></pre>
<p>关闭匿名访问:</p>
<pre><code>anonymous_enable=NO
</code></pre>
<p>去掉 local_enable 的注释,修改为开启:</p>
<pre><code>local_enable=YES
</code></pre>
<p>限制用户仅能访问自己的主目录:</p>
<pre><code>chroot_local_user=YES
</code></pre>
<p>设置用户的主目录:(不设置时,默认为用户的家目录<code>/home/userftp</code>)</p>
<pre><code>local_root=/data/test
</code></pre>
<p>重启服务:</p>
<pre><code>sudo service vsftpd restart
</code></pre>
<p>设置开机自启动:</p>
<pre><code>chkconfig vsftpd on
</code></pre>
<h2>连接测试</h2>
<pre><code>ftp userftp@112.126.74.124
ftp> pwd
Remote directory: /home/userftp
ftp> quit
221 Goodbye.
</code></pre>
<h2>参考</h2>
<p>1、<a rel="nofollow" href="https://www.digitalocean.com/community/tutorials/how-to-set-up-vsftpd-on-centos-6--2">https://www.digitalocean.com/community/tutorials/how-to-set-up-vsftpd-...</a><br>
2、<a rel="nofollow" href="http://koulitsu.blog.51cto.com/7355117/1221441">http://koulitsu.blog.51cto.com/7355117/1221441</a></p>
$_REQUEST 详解
https://segmentfault.com/a/1190000002794761
2015-05-26T00:10:01+08:00
2015-05-26T00:10:01+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<h2>前言</h2>
<p>在平时的开发中,我们可能会遇到以下问题:</p>
<ul>
<li>通过 $_REQUEST 得到值怎么和与 $_GET 获取到的不同?</li>
<li>$_SERVER 的值怎么是空的?</li>
<li>能通过 $_REQUEST 获取到 cookie 值吗?</li>
</ul>
<p>要想回答这几个问题,我们就需要详细了解一下 $_REQUEST 。</p>
<h2>PHP 相关配置</h2>
<p>首先来看看 PHP 配置文件 php.ini 中的相关配置:</p>
<pre><code>; This directive determines which super global arrays are registered when PHP
; starts up. G,P,C,E & S are abbreviations for the following respective super
; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty
; paid for the registration of these arrays and because ENV is not as commonly
; used as the others, ENV is not recommended on productions servers. You
; can still get access to the environment variables through getenv() should you
; need to.
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS";
; http://php.net/variables-order
variables_order = "GPCS"
</code></pre>
<p><strong>variables_order</strong>:这个配置项设置在 PHP 脚本启动时,要注册 EGPCS ($_ENV, $_GET,$_POST,$COOKIE,$_SERVER) 中哪几个超全局变量。</p>
<p>例如,如果设置 <code>variables_order = "SP"</code>,那么 PHP 将创建超全局变量 $_SERVER 和 $_POST,但是不会创建 $_ENV, $_GET 和 $_COOKIE。设置为 "",那么将不会创建超全局变量。</p>
<pre><code>; This directive determines which super global data (G,P & C) should be
; registered into the super global array REQUEST. If so, it also determines
; the order in which that data is registered. The values for this directive
; are specified in the same manner as the variables_order directive,
; EXCEPT one. Leaving this value empty will cause PHP to use the value set
; in the variables_order directive. It does not mean it will leave the super
; globals array REQUEST empty.
; Default Value: None
; Development Value: "GP"
; Production Value: "GP"
; http://php.net/request-order
request_order = "GP"
</code></pre>
<p><strong>request_order</strong>:这个配置项设置 PHP 将 GET, POST 和 Cookie 中的哪些添加到 $_REQUEST 中,并且指定了填充时的顺序。如果 request_order 设置为空,则填充的顺序会以 variables_order 配置项中的顺序为准。</p>
<p>例如,设置为 <code>request_order = "GP"</code> 时,代表 $_REQUEST 将包含 $_GET 和 $_POST 的值,并且当 $_GET 和 $_POST 中的键相同时,$_POST的值将覆盖 $_GET 的值。</p>
<h2>结论</h2>
<p>$_REQUEST 的值与 php.ini 中的配置相关。推荐在项目中尽量不要使用 $_REQUEST,而是明确的从 $_GET,$_POST,$COOKIE 中取值。</p>
<h2>参考资料</h2>
<p>1、<a rel="nofollow" href="http://php.net/variables-order">http://php.net/variables-order</a><br>
2、<a rel="nofollow" href="http://php.net/request-order">http://php.net/request-order</a><br>
3、<a rel="nofollow" href="https://github.com/php/php-src/blob/master/php.ini-production#L594-L618">https://github.com/php/php-src/blob/master/php.ini-production#L594-L61...</a></p>
brew update 时一些报错的解决方法
https://segmentfault.com/a/1190000002791161
2015-05-24T19:04:12+08:00
2015-05-24T19:04:12+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
2
<h2>错误一:Error: Failed to update tap: homebrew/dupes</h2>
<p>解决方案</p>
<pre><code>brew untap homebrew/dupes
brew untap homebrew/versions
brew prune
brew tap homebrew/dupes
brew tap homebrew/versions
</code></pre>
<p>参考:<a rel="nofollow" href="https://github.com/Homebrew/homebrew-dupes/issues/384">https://github.com/Homebrew/homebrew-dupes/issues/384</a></p>
<h2>错误二:Error: Permission denied - /usr/local/lib/dtrace/node.d</h2>
<p>解决方案</p>
<pre><code>brew link --overwrite node
sudo chown -R `whoami` /usr/local
</code></pre>
<p>参考:<a rel="nofollow" href="http://developpeers.com/blogs/fix-for-homebrew-permission-denied-issues">http://developpeers.com/blogs/fix-for-homebrew-permission-denied-issue...</a></p>
PHP 5.3、5.4、5.5、5.6 中的新特性
https://segmentfault.com/a/1190000002790818
2015-05-24T17:37:22+08:00
2015-05-24T17:37:22+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
29
<h2>PHP 5.6</h2>
<h3>1、可以使用表达式定义常量</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/migration56.new-features.php">https://php.net/manual/zh/migration56.new-features.php</a></p>
<p>在之前的 PHP 版本中,必须使用静态值来定义常量,声明属性以及指定函数参数默认值。 现在你可以使用包括数值、字符串字面量以及其他常量在内的数值表达式来 定义常量、声明属性以及设置函数参数默认值。</p>
<pre><code><?php
const ONE = 1;
const TWO = ONE * 2; //定义常量时允许使用之前定义的常量进行计算
class C {
const THREE = TWO + 1;
const ONE_THIRD = ONE / self::THREE;
const SENTENCE = 'The value of THREE is '.self::THREE;
public function f($a = ONE + self::THREE) { //允许常量作为函数参数默认值
return $a;
}
}
echo (new C)->f()."\n";
echo C::SENTENCE;
?>
</code></pre>
<p>可以通过 const 关键字来定义类型为 array 的常量。</p>
<pre><code><?php
const ARR = ['a', 'b'];
echo ARR[0];
?>
</code></pre>
<h3>2、使用 <code>...</code> 运算符定义变长参数函数</h3>
<p>现在可以不依赖 func_get_args(), 使用 ... 运算符 来实现 变长参数函数。</p>
<pre><code><?php
function test(...$args)
{
print_r($args);
}
test(1,2,3);
//输出
Array
(
[0] => 1
[1] => 2
[2] => 3
)
?>
</code></pre>
<h3>3、使用 <code>**</code> 进行幂运算</h3>
<p>加入右连接运算符 ** 来进行幂运算。 同时还支持简写的 **= 运算符,表示进行幂运算并赋值。</p>
<pre><code>printf(2 ** 3); // 8
$a = 2;
$a **= 3;
printf($a); // 8
</code></pre>
<h3>4、use function 以及 use const</h3>
<p>use 运算符可以在类中导入外部的函数和常量了。 对应的结构为 use function 和 use const。</p>
<pre><code><?php
namespace Name\Space {
const FOO = 42;
function f() { echo __FUNCTION__."\n"; }
}
namespace {
use const Name\Space\FOO;
use function Name\Space\f;
echo FOO."\n";
f();
}
?>
</code></pre>
<h3>5、加入 <code>hash_equals()</code> 函数,以恒定的时间消耗来进行字符串比较,以避免时序攻击</h3>
<pre><code><?php
$expected = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$incorrect = crypt('1234', '$2a$07$usesomesillystringforsalt$');
var_dump(hash_equals($expected, $incorrect)); // false
?>
</code></pre>
<h3>6、加入 __debugInfo()</h3>
<p>当使用 var_dump() 输出对象的时候,可以用来控制要输出的属性和值。返回值必须是个数组。</p>
<pre><code><?php
class C {
private $prop;
public function __construct($val) {
$this->prop = $val;
}
public function __debugInfo() {
return array(
"prop" => $this->prop
);
}
}
var_dump(new C(42));
?>
</code></pre>
<h2>PHP 5.5</h2>
<h3>1、新增 Generators</h3>
<p>yield关键字用于当函数需要返回一个迭代器的时候,逐个返回值。</p>
<pre><code>function number10()
{
for($i = 1; $i <= 10; $i += 1)
yield $i;
}
</code></pre>
<p>该函数的返回值是一个数组:</p>
<pre><code>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</code></pre>
<h3>2、新增 finally 关键字</h3>
<p>Finally处理流程:</p>
<p><img src="/img/bVlR4N" alt="图片描述"></p>
<h3>3、foreach 支持 list()</h3>
<p>foreach 支持通过 list() 将嵌套数组分离到单独的变量。</p>
<pre><code><?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($a, $b)) {
echo $a.$b\n";
}
?>
</code></pre>
<h3>4、empty() 支持传入一个任意表达式,而不仅是一个变量</h3>
<pre><code><?php
function always_false() {
return false;
}
if (empty(always_false())) {
echo 'This will be printed.';
}
</code></pre>
<h3>5、直接通过下标获取访问数组和字符串字面量的元素或字符</h3>
<pre><code>```
echo [1, 2, 3][0]; // 1
echo 'PHP'[0]; // P
```
</code></pre>
<h3>6、新的密码哈希 API</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/book.password.php">https://php.net/manual/zh/book.password.php</a></p>
<p>缺点是缺乏互操作性,在需要和其他语言对接时会比较麻烦。</p>
<pre><code>//加密
echo $hash = password_hash('rasmuslerdorf', PASSWORD_DEFAULT);
//输出结果类似于:$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
//验证
if(password_verify('rasmuslerdorf','$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a')) {
echo "密码正确";
} else {
echo "密码错误";
}
</code></pre>
<h3>7、新增 boolval() 函数</h3>
<p>PHP已经实现了strval、intval和floatval的函数。为了达到一致性将添加boolval函数。</p>
<h3>8、新增 array_column() 函数</h3>
<p>可用来返回数组中指定的一列。</p>
<pre><code>$records = array(
array('id' => 2135,'name' => 'John'),
array('id' => 3245,'name' => 'Smith'),
array('id' => 5342,'name' => 'Peter')
);
//从结果集中取出 name 列
$names = array_column($records, 'name');
print_r($names);
//从结果集中总取出 name 列,用相应的 id 作为键值
$names = array_column($records, 'name', 'id');
print_r($names);
</code></pre>
<h2>PHP 5.4</h2>
<h3>1、新增 Traits</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/language.oop5.traits.php">https://php.net/manual/zh/language.oop5.traits.php</a></p>
<pre><code>// Traits不能被单独实例化,只能被类所包含
trait SayWorld
{
public function sayHello()
{
echo 'World!';
}
}
class MyHelloWorld
{
// 将SayWorld中的成员包含进来
use SayWorld;
}
$xxoo = new MyHelloWorld();
// sayHello() 函数是来自 SayWorld 构件的
$xxoo->sayHello();
</code></pre>
<h3>2、新增短数组语法</h3>
<pre><code>// 原来的数组写法
$arr = array("key" => "value", "key2" => "value2");
$arr = array(1,2,3,4);
// 简写形式
$arr = ["key" => "value", "key2" => "value2"];
$arr = [1,2,3,4];
</code></pre>
<h3>3、新增支持对函数返回数组的成员访问解析</h3>
<pre><code>print func()[0];
</code></pre>
<h3>4、无论 php.ini 中是否设置 short_open_tag, 格式总是可用。</h3>
<p>这种简写形式被称为 Short Open Tag, 在 PHP5.3 起被默认开启,在 PHP5.4 起总是可用。 使用这种简写形式在 HTML 中嵌入 PHP 变量将会非常方便。</p>
<h3>5、内置用于开发的 CLI 模式的 web server</h3>
<pre><code>//启动Web服务器
php -S localhost:8000
//启动时指定根目录
php -S localhost:8000 -t /home/me/public_html/foo
//使用路由(Router)脚本
php -S localhost:8000 index.php //所有的请求都会由index.php来处理。
</code></pre>
<h3>6、新增在实例化时访问类成员</h3>
<pre><code> (new Foo)->bar();
</code></pre>
<h3>7、新增了动态访问静态方法的方式</h3>
<pre><code>$func = "funcXXOO";
A::{$func}();
</code></pre>
<h3>8、闭包支持 $this</h3>
<h3>9、新增二进制直接量</h3>
<pre><code>$bin = bindec('110011'); //之前需要这样写
$bin = 0b110011;
echo $bin; //51
</code></pre>
<h3>10、session提供了上传进度支持</h3>
<p>通过 <code>$_SESSION["upload_progress_name"]</code> 就可以获得当前文件上传的进度信息,结合 Ajax 就能很容易的实现上传进度条。</p>
<h3>11、默认使用 mysqlnd</h3>
<p>现在mysql, mysqli, pdo_mysql默认使用mysqlnd本地库,在PHP5.4以前需要:<code>./configure --with-mysqli=mysqlnd</code><br>
现在:<code>./configure --with-mysqli</code></p>
<h3>12、让 json 更懂中文</h3>
<pre><code>echo json_encode("中文", JSON_UNESCAPED_UNICODE);
//"中文"
</code></pre>
<h3>13、default_charset从ISO-8859-1已经变为UTF-8</h3>
<p>默认发送“Content-Type: text/html; charset=utf-8”</p>
<h2>PHP 5.3</h2>
<h3>1、支持命名空间</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/language.namespaces.php">https://php.net/manual/zh/language.namespaces.php</a></p>
<pre><code><?php
namespace my\name; // 定义命名空间
class MyClass {}
const MYCONST = 1;
$a = new \my\name\MyClass;
$class = __NAMESPACE__.'\MyClass';
$b = new $class;
$c = \my\name\MYCONST;
$d = namespace\MYCONST;
var_dump($a,$b,$c,$d);
/*
object(my\name\MyClass)#1 (0) {
}
object(my\name\MyClass)#2 (0) {
}
int(1)
int(1)
*/
?>
</code></pre>
<h3>2、增加后期静态绑定</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/language.oop5.late-static-bindings.php">https://php.net/manual/zh/language.oop5.late-static-bindings.php</a></p>
<p>在PHP中,我们可以在类中通过self关键字或者<strong>CLASS</strong>来判断或调用当前类。但有一个问题,如果我们是在子类中调用,得到的结果将是父类。因为在继承父类的时候,静态成员就已经被绑定了。</p>
<pre><code>class A
{
static public function callFuncXXOO()
{
print self::funcXXOO();
}
static public function funcXXOO()
{
return "A::funcXXOO()";
}
}
class B extends A
{
static public function funcXXOO()
{
return "B::funcXXOO";
}
}
$b = new B;
$b->callFuncXXOO();
</code></pre>
<p>输出是:</p>
<pre><code>A::funcXXOO()
</code></pre>
<p>PHP 5.3.0中增加了一个static关键字来引用当前类,即实现了延迟静态绑定:</p>
<pre><code>class A
{
static public function callFuncXXOO()
{
print static::funcXXOO();
}
// ...
}
// ...
</code></pre>
<p>这样就会像预期一样输出了:</p>
<pre><code>B::funcXXOO
</code></pre>
<h3>3、增加 goto 操作符</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/control-structures.goto.php">https://php.net/manual/zh/control-structures.goto.php</a></p>
<p>goto 语句有可能会导致程序流程不清晰,可读性减弱,但在某些情况下具有其独特的方便之处,例如中断深度嵌套的循环和 if 语句。</p>
<pre><code><?php
goto test;
echo '1';
test:
echo '2';
?>
//以上运行时会输出 2
</code></pre>
<h3>4、添加了原生的闭包(Lambda/匿名函数)支持</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/functions.anonymous.php">https://php.net/manual/zh/functions.anonymous.php</a></p>
<h3>5、新增两个魔术方法, __callStatic 和 __invoke</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/language.oop5.magic.php">https://php.net/manual/zh/language.oop5.magic.php</a></p>
<p>用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。<br>
当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。</p>
<pre><code>class A
{
public function __invoke($str)
{
print "A::__invoke(): {$str}";
}
}
$a = new A;
$a("Hello World");
</code></pre>
<p>输出是:</p>
<pre><code>A::__invoke(): Hello World
</code></pre>
<h3>6、添加 Nowdoc 语法支持</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/language.types.string.php#language.types.string.syntax.nowdoc">https://php.net/manual/zh/language.types.string.php#language.types.str...</a></p>
<pre><code><?php
$str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc syntax.
EOD;
</code></pre>
<p>就象 heredoc 结构类似于双引号字符串,Nowdoc 结构是类似于单引号字符串的。Nowdoc 结构很象 heredoc 结构,但是 nowdoc 中不进行解析操作。</p>
<h3>7、Heredoc 结构中可以用双引号来声明标识符了。</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/language.types.string.php#language.types.string.syntax.heredoc">https://php.net/manual/zh/language.types.string.php#language.types.str...</a></p>
<pre><code><?php
echo <<<"FOOBAR"
Hello World!
FOOBAR;
?>
</code></pre>
<h3>8、const 关键字可用来在类定义之外定义常量了</h3>
<p><a rel="nofollow" href="https://php.net/manual/zh/language.constants.syntax.php">https://php.net/manual/zh/language.constants.syntax.php</a></p>
<pre><code><?php
define("CONSTANT_A", "Hello world");
const CONSTANT_B = 'Hello World';
</code></pre>
<p>const 形式仅适用于常量,不适用于运行时才能求值的表达式:</p>
<pre><code>// 正确
const XXOO = 1234;
// 错误
const XXOO = 2 * 617;
</code></pre>
<p>和使用 define() 来定义常量不同的是,使用 const 关键字定义常量必须处于最顶端的作用域,因为用此方法是在编译时定义的。即不能在函数内,循环内以及 if 语句之内用 const 来定义常量。</p>
<h3>9、三元运算符可以简写省略中间的部分</h3>
<p>表达式 expr1 ?: expr3 ,当 expr1 为 TRUE 时返回 expr1,否则返回 expr3。</p>
<h3>10、异常可以嵌套了</h3>
<pre><code><?php
class MyException extends Exception { }
class Test {
public function testing() {
try {
try {
throw new MyException('foo!');
} catch (MyException $e) {
/* rethrow it */
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
}
$foo = new Test;
$foo->testing();
?>
</code></pre>
<h3>11、可以动态访问静态变量了</h3>
<pre><code><?php
class C {
public static $foo = 123;
}
$a = "C";
echo $a::$foo;
?>
</code></pre>
<p>上边运行时输出:</p>
<pre><code>123
</code></pre>
<h3>12、mail()函数支持记录发送日志了</h3>
<p>在配置文件 php.ini 中可设置日志路径。参数名:mail.log</p>
<h2>参考资料</h2>
<p>1、<a rel="nofollow" href="https://php.net/manual/zh/migration53.new-features.php">https://php.net/manual/zh/migration53.new-features.php</a><br>
2、<a rel="nofollow" href="https://php.net/manual/zh/migration54.new-features.php">https://php.net/manual/zh/migration54.new-features.php</a><br>
3、<a rel="nofollow" href="https://php.net/manual/zh/migration55.new-features.php">https://php.net/manual/zh/migration55.new-features.php</a><br>
4、<a rel="nofollow" href="https://php.net/manual/zh/migration56.new-features.php">https://php.net/manual/zh/migration56.new-features.php</a><br>
5、<a rel="nofollow" href="http://segmentfault.com/a/1190000000403307">http://segmentfault.com/a/1190000000403307</a><br>
6、<a rel="nofollow" href="http://blog.csdn.net/heiyeshuwu/article/details/16884725">http://blog.csdn.net/heiyeshuwu/article/details/16884725</a></p>
使用 ab 进行压力测试
https://segmentfault.com/a/1190000002790015
2015-05-24T12:35:40+08:00
2015-05-24T12:35:40+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<h2>命令</h2>
<pre><code>ab -n 10000 -c 100 http://aso100.com/index.php/rank
</code></pre>
<p>-n:代表请求数<br>
-c:代表并发数<br>
-H:添加请求头,例如 ‘Accept-Encoding: gzip’,以gzip方式请求。</p>
<p>-n 10000 -c 100 即一共进行10000次请求,每次并发数为100.</p>
<h2>结果</h2>
<pre><code>[root@a2 ~]# ab -n 10000 -c 200 http://aso100.com/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking aso100.com (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software: nginx/1.6.3
Server Hostname: aso100.com
Server Port: 80
Document Path: /
Document Length: 6299 bytes
Concurrency Level: 200
Time taken for tests: 19.562 seconds
Complete requests: 10000
Failed requests: 9
(Connect: 0, Receive: 0, Length: 9, Exceptions: 0)
Write errors: 0
Non-2xx responses: 9
Total transferred: 66722805 bytes
HTML transferred: 62934857 bytes
#吞吐率,计算公式:Complete requests / Time taken for tests
Requests per second: 511.19 [#/sec] (mean)
#用户平均请求等待时间,Time taken for tests /Complete requests
Time per request: 391.241 [ms] (mean)
#服务器平均请求等待时间,Time taken for tests / (Complete requests /Concurrency Level)
Time per request: 1.956 [ms] (mean, across all concurrent requests)
Transfer rate: 3330.89 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 110 512.1 0 15000
Processing: 10 268 139.6 248 4640
Waiting: 7 268 139.6 248 4640
Total: 59 378 570.0 250 16715
Percentage of the requests served within a certain time (ms)
50% 250 ## 50%的请求在250ms内返回
66% 260 ## 60%的请求在260ms内返回
75% 275
80% 290
90% 375
95% 1249
98% 1304
99% 2641
100% 16715 (longest request)
</code></pre>
Nginx 配置文件详解
https://segmentfault.com/a/1190000002789743
2015-05-24T01:45:51+08:00
2015-05-24T01:45:51+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
4
<h2>顶级配置</h2>
<pre><code>#定义 Nginx 运行的用户和用户组
user nginx;
#进程文件
pid /var/run/nginx.pid;
#错误日志位置和级别,debug、info、notice、warn、error、crit
error_log /var/log/nginx/error.log warn;
#Nginx worker 的进程数,一般可设置为可用的CPU内核数。
worker_processes 8;
#每个 worker 打开文件描述符的最大数量限制。理论值应该是最多打开文件数(系统的值ulimit -n)与 nginx 进程数相除,但是 nginx 分配请求并不均匀,所以建议与ulimit -n的值保持一致。
worker_rlimit_nofile 65535;
</code></pre>
<p>修改系统文件打开数量限制:</p>
<pre><code>sudo sh -c ulimit -HSn 65535 //临时修改
</code></pre>
<p>重启后永久生效,则需要设置修改:</p>
<pre><code>sudo vim /etc/security/limits.conf
</code></pre>
<p>在文件尾部添加:</p>
<pre><code>* soft nofile 200000
* hard nofile 200000
</code></pre>
<h2>Events 模块</h2>
<pre><code>events {
#设置一个worker进程同时打开的最大连接数
worker_connections 2048;
#告诉nginx收到一个新连接通知后接受尽可能多的连接
multi_accept on;
#设置用于复用客户端线程的轮询方法。如果你使用Linux 2.6+,你应该使用epoll。如果你使用*BSD,你应该使用kqueue。
use epoll;
}
</code></pre>
<h2>HTTP 模块</h2>
<pre><code>http {
#隐藏 Nginx 的版本号,提高安全性。
server_tokens off;
#开启高效文件传输模式,sendfile 指令指定 Nginx 是否调用sendfile 函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的负载。
sendfile on;
#是否开启目录列表访问,默认关闭。
autoindex off;
#告诉 Nginx 在一个数据包里发送所有头文件,而不一个接一个的发送
tcp_nopush on;
#告诉 Nginx 不要缓存数据,而是一段一段的发送--当需要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能立即得到返回值。Nginx 默认会始终工作在 tcp nopush 状态下。但是当开启前面的 sendfile on; 时,它的工作特点是 nopush 的最后一个包会自动转转换到 nopush off。为了减小那200ms的延迟,开启 nodelay on; 将其很快传送出去。结论就是 sendfile on; 开启时,tcp_nopush 和 tcp_nodelay 都是on 是可以的。
tcp_nodelay on;
#日志格式设定
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#定义访问日志,设置为 off 可以关闭日志,提高性能
access_log /var/log/nginx/access.log main;
#连接超时时间,单位是秒
keepalive_timeout 120;
#读取HTTP头部的超时时间,默认值 60。客户端与服务器建立连接后将开始接收HTTP头部,在这个过程中,如果在一个时间间隔(超时时间)内没有读取到客户端发来的字节,则认为超时,并向客户端返回408 ("Request timed out")响应。
client_header_timeout 60;
#默认值 60。与client_header_timeout相似,只是这个超时时间只在读取HTTP包体时才有效。
client_body_timeout 10;
#发送响应的超时时间,默认值 60。即Nginx服务器向客户端发送了数据包,但客户端一直没有去接收这个数据包。如果某个连接超过send_timeout定义的超时时间,那么Nginx将会关闭这个连接。
send_timeout 60;
#连接超时后将通过向客户端发送RST包来直接重置连接。这个选项打开后,Nginx会在某个连接超时后,不是使用正常情形下的四次握手关闭TCP连接,而是直接向用户发送RST重置包,不再等待用户的应答,直接释放Nginx服务器上关于这个套接字使用的所有缓存(如TCP滑动窗口)。相比正常的关闭方式,它使得服务器避免产生许多处于FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT状态的TCP连接。注意,使用RST重置包关闭连接会带来一些问题,默认情况下不会开启。
reset_timedout_connection off;
#要限制连接,必须先有一个容器对连接进行计数,"zone=" 是给它一个名字,可以随便叫,这个名字要跟下面的 limit_conn 一致。$binary_remote_addr 用二进制来储存客户端的地址,1m 可以储存 32000 个并发会话。
limit_conn_zone $binary_remote_addr zone=addr:5m;
#给定的key设置最大连接数。这里key是addr,我们设置的值是100,也就是说我们允许每一个IP地址最多同时打开有100个连接。
limit_conn addr 100;
#对每个连接限速100k。这如果一个IP允许两个并发连接,那么这个IP就是限速200K。
limit_rate 100k;
#include 是一个在当前文件中包含另一个文件内容的指令。这里我们使用它来加载文件扩展名与文件类型映射表。nginx根据映射关系,设置http请求响应头的Content-Type值。当在映射表找不到时,使用nginx.conf中default-type指定的默认值。
include /etc/nginx/mime.types;
#设置文件使用的默认的MIME-type
default_type text/html;
#默认编码
charset UTF-8;
#该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的CPU资源消耗。该模块启用后,nginx首先检查是否存在请求静态文件的gz结尾的文件,如果有则直接返回该gz文件内容。
gzip_static off;
#开启 gzip 压缩。
gzip on;
# 禁用客户端为 IE6 时的 gzip功能。
gzip_disable "msie6";
#Nginx做为反向代理的时候启用。可选值:off|expired|no-cache|no-sotre|private|no_last_modified|no_etag|auth|any
gzip_proxied any;
#设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。建议设置成大于1k的字节数,小于1k可能会越压越大。
gzip_min_length 1024;
#设置数据的压缩等级。这个等级可以是1-9之间的任意数值,9是最慢但是压缩比最大的。
gzip_comp_level 5;
#设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。 例如 4 4k 代表以4k为单位,按照原始数据大小以4k为单位的4倍申请内存。如果没有设置,默认值是申请跟原始数据相同大小的内存空间去存储gzip压缩结果。
gzip_buffers 4 16k;
#设置需要压缩的数据格式。Nginx默认只对text/html进行压缩。
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
#为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。
open_file_cache max=65535 inactive=30s;
#多长时间检查一次缓存的有效信息
open_file_cache_valid 30s;
#open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的。出现 Last-Modified 不变的情况,就是因为当nginx对一个静态文件缓存后,如果30s内还在访问它,那么它的缓存就一直存在,直到30s内你不访问了为止。
open_file_cache_min_uses 2;
#是否记录cache错误
open_file_cache_errors on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
</code></pre>
<h2>SERVER 模块</h2>
<pre><code>server {
#监听端口,nginx 会根据请求的 HOST 来决定使用哪个 SERVER 段的配置。如果没有匹配的 server_name,则默认使用配置文件中第一个。加上 default_server 则可以以指定没有匹配时的默认规则。
#listen 80;
listen 80 default_server;
#域名可以有多个,用空格隔开
server_name www.test.com test.com;
root /user/share/nginx/html/test;
#404页面配置
error_page 404 /404.html;
#配置 ssl,有需要时开启。
ssl on;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
location / {
index index.html index.php;
}
#图片缓存时间设置
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 10d;
}
#JS和CSS缓存时间设置
location ~ .*.(js|css)?$ {
expires 1h;
}
location ~ [^/]\.php(/|$) {
fastcgi_index index.php;
#开启 PATH_INFO 支持,作用就是把参数按照给定的正则表达式分割成 $fastcgi_script_name 和 $fastcgi_path_info。
#例如:请求 index.php/id/1 不加此行配置时,fastcgi_script_name 是 /index.php/id/1,fastcgi_path_info 是空。
#加上之后,fastcgi_script_name 是 index.php,fastcgi_path_info 是 /id/1
fastcgi_split_path_info ^(.+\.php)(.*)$;
#此值即是 PHP 中 $_SERVER['SCRIPT_FILENAME'] 的值
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
#指定FastCGI服务器监听端口与地址。须和 PHP-FPM 的设置相同。
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
}
}
</code></pre>
<h2>参考资料</h2>
<p>1、<a rel="nofollow" href="http://nginx.org/en/docs/">http://nginx.org/en/docs/</a><br>
2、<a rel="nofollow" href="http://www.oschina.net/translate/nginx-setup">http://www.oschina.net/translate/nginx-setup</a><br>
3、<a rel="nofollow" href="http://www.ha97.com/5194.html">http://www.ha97.com/5194.html</a></p>
Linux 下删除大量文件
https://segmentfault.com/a/1190000002785069
2015-05-22T01:10:40+08:00
2015-05-22T01:10:40+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
1
<p>一、直接删除</p>
<pre><code>find . -name "*.log" | xargs rm -r
</code></pre>
<p>二、慢速删除</p>
<p>保存下边脚本为 slowRemove.sh,并添加可执行权限 <code>chmod +x slowRemove.sh</code>。通过 sleep,降低服务器硬盘负载压力。</p>
<pre><code>#!/bin/bash
for name in `find /mnt/to-delete -name "*" -print`
do
echo $name
rm -f $name
sleep 0.01
done
</code></pre>
Some PHP Coding Tips「2015年05月25日更新」
https://segmentfault.com/a/1190000002784996
2015-05-21T23:29:06+08:00
2015-05-21T23:29:06+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
1
<h3>1、使用list来实现一次获取explode后的特定段值:</h3>
<pre><code><?php
list( , $mid) = explode(';', 'aa;bb;cc');
echo $mid; //输出 bb
</code></pre>
<h3>2、注意 == 、switch、in_array 的松比较 (loose comparision)</h3>
<p>例如下边的例子中,如果 $name 值为 0,那么它会满足任何一条 case。</p>
<pre><code>switch ($name) {
case "danny":
...
break;
case "eve":
...
break;
}
</code></pre>
<p>解决方法:在 switch 之前,把变量类型转换成所期望的类型。 而 in_array 提供了第三个参数,如果第三个参数的值为 TRUE 则 in_array() 函数还会检查变量的类型是否相同。(参考:<a rel="nofollow" href="https://php.net/manual/zh/function.in-array.php">https://php.net/manual/zh/function.in-array.php</a>)</p>
<pre><code>switch (strval($name)) {
case "danny":
...
break;
case "eve":
...
break;
}
</code></pre>
<h3>3、用 switch 来改写 if else</h3>
<p>例如:</p>
<pre><code>if($a) {
} else if ($b) {
} else if ($c || $d) {
}
</code></pre>
<p>可以简单改写为更清晰的:</p>
<pre><code>switch (TRUE) {
case $a:
break;
case $b:
break;
case $c:
case $d:
break;
}
</code></pre>
<h3>4、不用第三变量交换俩个变量的值</h3>
<p>list($a, $b) = array($b, $a);</p>
<h3>5、使用 array_map 遍历数组</h3>
<p>在从数据库取回记录后,经常要 foreach 去取其中一个字段,这时就可以使用 array_map 来简化代码。</p>
<pre><code>$uids = array_map( function($user){ return $user['id']; } , $users );
</code></pre>
<h3>6、sleep 的参数不能是浮点数</h3>
<p><code>sleep(0.25)</code> 会被转化为 <code>sleep(0)</code>,可以使用 sleep('250000') 来替代。</p>
<h3>参考</h3>
<ol>
<li><a rel="nofollow" href="http://www.laruence.com/2011/03/24/858.html">http://www.laruence.com/2011/03/24/858.html</a></li>
<li><a rel="nofollow" href="http://get.jobdeer.com/75.card">http://get.jobdeer.com/75.card</a></li>
</ol>
PHP 中的 == 和“隐式转换”
https://segmentfault.com/a/1190000002784965
2015-05-21T23:00:52+08:00
2015-05-21T23:00:52+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
3
<h3>引言</h3>
<p>最近,在 Hacker News 上有一篇帖子(<a rel="nofollow" href="https://news.ycombinator.com/item?id=9484757">https://news.ycombinator.com/item?id=9484757</a>),提到了一种探测网站密码加密方式的方法。</p>
<pre><code><?php
var_dump(md5('240610708') == md5('QNKCDZO'));
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
var_dump('0x1234Ab' == '1193131');
</code></pre>
<p>结果都是:</p>
<pre><code>bool(true)
bool(true)
bool(true)
</code></pre>
<p>如果在一个网站,使用240610708作为密码,然后用QNKCDZO登陆,结果可以登录的话,说明密码是以MD5方式保存的。类似的,如果用aaroZmOk作为密码,然后用aaK1STfY登陆,结果可以登录的话,说明密码是以sha1方式保存的。第三种当然就是明文存储了。</p>
<h2>分析</h2>
<p>以第一组数为例:</p>
<pre><code>md5('240610708') 的结果是:0e462097431906509019562988736854
md5('QNKCDZO') 的结果是:0e830400451993494058024219903391
</code></pre>
<p>由于 PHP 是弱类型语言,在使用 == 号时,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。此规则也适用于 switch 语句。上述例子中的两个字符串恰好以 0e 的科学记数法开头,字符串被隐式转换为浮点数,实际上也就等效于 0×10^0 ,因此比较起来是相等的。</p>
<h2>类似</h2>
<pre><code><?php
var_dump( 0 == "a" );
var_dump( "0" == "a" );
</code></pre>
<p>第一个返回的是 <code>true</code>,第二个返回的是 <code>false</code></p>
<h2>结论</h2>
<p>PHP中的Hash校验,应该使用“===”,而不应该使用“==”。另外如果生产环境版本足够高的话(PHP >= 5.6.0),最好使用 <code>hash_equals()</code> 函数。</p>
<p><code>hash_equals()</code> 在比较两个字符串,无论它们是否相等,函数的时间消耗是恒定的,可以用来防止时序攻击。</p>
Beanstalkd 使用记录
https://segmentfault.com/a/1190000002784775
2015-05-21T21:06:18+08:00
2015-05-21T21:06:18+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
8
<h2>一、安装</h2>
<h3>1、官网</h3>
<p><a href="https://link.segmentfault.com/?enc=%2FRF44utb4c8Z8Zv1GggaoA%3D%3D.CqopCpdZH%2FOI7C%2F1kI%2BKGLcyvF5Wq%2FtC8RcAzWr5v0rA5j2gQT3fTN1FJquyvV5Z" rel="nofollow">https://kr.github.io/beanstalkd/</a></p>
<h3>2、安装</h3>
<pre><code>yum install beanstalkd --enablerepo=epel</code></pre>
<h3>3、启动</h3>
<pre><code>/usr/bin/beanstalkd -l 0.0.0.0 -p 11300 -b /var/lib/beanstalkd/binlog -F</code></pre>
<p><code>-b</code> 开启binlog,断电后重启会自动恢复任务。</p>
<h3>4、配置文件</h3>
<pre><code>/etc/sysconfig/beanstalkd</code></pre>
<h2>二、基本概念</h2>
<h3>1、Beanstalkd设计里面的核心概念:</h3>
<ul>
<li><p><strong>job</strong>:一个需要异步处理的任务,是 Beanstalkd 中的基本单元,需要放在一个 tube 中。</p></li>
<li><p><strong>tube</strong>:一个有名的任务队列,用来存储统一类型的 job,是 producer 和 consumer 操作的对象。</p></li>
<li><p><strong>producer</strong>:Job 的生产者,通过 put 命令来将一个 job 放到一个 tube 中。</p></li>
<li><p><strong>consumer</strong>:Job的消费者,通过 reserve/release/bury/delete 命令来获取 job 或改变 job 的状态。</p></li>
</ul>
<h3>2、job 的生命周期</h3>
<p><img src="/img/bVlQBK" alt="图片描述" title="图片描述"></p>
<p>当producer直接put一个job时,job就处于READY状态,等待consumer来处理,如果选择延迟put,job就先到DELAYED状态,等待时间过后才迁移到READY状态。consumer获取了当前READY的job后,该job的状态就迁移到RESERVED,这样其他的consumer就不能再操作该job。当consumer完成该job后,可以选择delete, release或者bury操作;delete之后,job从系统消亡,之后不能再获取;release操作可以重新把该job状态迁移回READY(也可以延迟该状态迁移操作),使其他的consumer可以继续获取和执行该job;有意思的是bury操作,可以把该job休眠,等到需要的时候,再将休眠的job kick回READY状态,也可以delete BURIED状态的job。正是有这些有趣的操作和状态,才可以基于此做出很多意思的应用,比如要实现一个循环队列,就可以将RESERVED状态的job休眠掉,等没有READY状态的job时再将BURIED状态的job一次性kick回READY状态。</p>
<ul>
<li><p>READY - 需要立即处理的任务,当延时 (DELAYED) 任务到期后会自动成为当前任务;</p></li>
<li><p>DELAYED - 延迟执行的任务, 当消费者处理任务后, 可以用将消息再次放回 DELAYED 队列延迟执行;</p></li>
<li><p>RESERVED - 已经被消费者获取, 正在执行的任务。Beanstalkd 负责检查任务是否在 TTR(time-to-run) 内完成;</p></li>
<li><p>BURIED - 保留的任务: 任务不会被执行,也不会消失,除非有人把它 "踢" 回队列;</p></li>
<li><p>DELETED - 消息被彻底删除。Beanstalkd 不再维持这些消息。</p></li>
</ul>
<h3>3、一些特性</h3>
<h4>优先级</h4>
<p>任务 (job) 可以有 0~2^32 个优先级, 0 代表最高优先级,默认优先级为1024。</p>
<h4>持久化</h4>
<p>可以通过binlog将job及其状态记录到文件里面,在Beanstalkd下次启动时可以通过读取binlog来恢复之前的job及状态。</p>
<h4>分布式容错</h4>
<p>分布式设计和Memcached类似,beanstalkd各个server之间并不知道彼此的存在,都是通过client来实现分布式以及根据tube名称去特定server获取job。</p>
<h4>超时控制</h4>
<p>为了防止某个consumer长时间占用任务但不能处理的情况,Beanstalkd为reserve操作设置了timeout时间,如果该consumer不能在指定时间内完成job,job将被迁移回READY状态,供其他consumer执行。</p>
<h2>三、Client Libraries For PHP</h2>
<p>项目地址:<a href="https://link.segmentfault.com/?enc=clbJbibrPwM%2F4akH%2Bx9Vig%3D%3D.1ZJqbnTDt9fMvoC7IoQV5Thu3kbvSRb0LHrkwjiVdNhWpkKaWOQc%2F8wovMedXndQ" rel="nofollow">https://github.com/pda/pheanstalk/</a></p>
<h3>1、Producer 示例:向队列中添加job</h3>
<pre><code>$pheanstalk = new Pheanstalk_Pheanstalk('127.0.0.1');
$pheanstalk ->useTube('tubeName') ->put($jobData);</code></pre>
<h3>2、Consumer 示例:从队列中取出job</h3>
<pre><code>$job = $pheanstalk ->watch('tubeName') ->ignore('default') ->reserve();
echo $job->getData();
$pheanstalk->delete($job);</code></pre>
<h3>3、检查服务状态</h3>
<pre><code>$isAlive = $pheanstalk->getConnection()->isServiceListening(); //返回 true 或 false</code></pre>
<h3>4、获取某一 tube 的数据</h3>
<pre><code>try{
$tubeStatus = $pheanstalk->statsTube('tubeName');
} catch (Exception $e){
if($e->getMessage()=='Server reported NOT_FOUND'){ //tube 不存在
$current_jobs_ready = 0;
}
}</code></pre>
<h2>四、其他</h2>
<h3>1、PHP 版控制台</h3>
<p><a href="https://link.segmentfault.com/?enc=L1ra2RTQLEFaNFSkCAiXQg%3D%3D.cz9Vt1xjFDmfUkdY14EbBTGFLCSKhCulVP9nC%2FCCgqCmjc5P3gHomUpTBCnLZkqB" rel="nofollow">https://github.com/ptrofimov/beanstalk_console</a></p>
<h3>2、Chrome 插件</h3>
<p><a href="https://link.segmentfault.com/?enc=FaQmi2JNQu1FG%2Br%2F0xVoQA%3D%3D.3rz3VA6atmk4XeGSXV3%2FLiovlX9xfNjo5jbxr6u6yiXVY6CIozeJ4hY1Do93Z73u0KV0UAuRHp%2BKnRqWCeQS1GBr1x91kLgaTTqa3Jb0pDqg8m4LP5OZbDCsi%2FPvTXDS" rel="nofollow">https://chrome.google.com/webstore/detail/beanstalkd-dashboard/dakkekjnlffnecpmdiamebeooimjnipm</a></p>
<h2>五、参考资料</h2>
<ol>
<li><p><a href="https://link.segmentfault.com/?enc=QBXJFzzDMWEd1duHHSeI4w%3D%3D.NjfY3wjRC2JyVMqzkNrI5uFh%2F6mjcamrfBSs5RFs807i9uky%2BZWbKGHH8136O%2BSj" rel="nofollow">https://github.com/kr/beanstalkd/wiki/faq</a></p></li>
<li><p><a href="https://link.segmentfault.com/?enc=ikzNOOle5M7L7xwF2Nv87w%3D%3D.SBLFF4MZk6ykEnLo6nwZAd1%2BwEG7i8pyZ2jO38553lc%3D" rel="nofollow">http://csrd.aliapp.com/?p=1201</a></p></li>
</ol>
通过 XtraBackup 实现不停机不锁表搭建主从同步
https://segmentfault.com/a/1190000002575399
2015-03-03T18:34:31+08:00
2015-03-03T18:34:31+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
4
<h2>简介</h2>
<p>Xtrabackup是由 Percona 开发的一个开源软件,可实现对 InnoDB 的数据备份,支持在线热备份(备份时不影响数据读写)。备份时,Xtrabackup 会将 Master 的 binlog 信息记录在 xtrabackup_slave_info 文件中,通过此信息可以方便的搭建主从复制。</p>
<p>XtraBackup 有两个工具:xtrabackup 和 innobackupex:</p>
<ul>
<li>xtrabackup 本身只能备份 InnoDB 和 XtraDB ,不能备份 MyISAM;</li>
<li>innobackupex 本身是 Hot Backup 脚本修改而来,同时可以备份 MyISAM 和 InnoDB,但是备份 MyISAM 需要加读锁。</li>
</ul>
<p>官网:<a rel="nofollow" href="http://www.percona.com/software/percona-xtrabackup">http://www.percona.com/software/percona-xtrabackup</a><br>
文档:<a rel="nofollow" href="http://www.percona.com/doc/percona-xtrabackup/2.2/index.html">http://www.percona.com/doc/percona-xtrabackup/2.2/index.html</a></p>
<p><em>注:本文服务器环境为 CentOS,其他环境请自行修改实现。</em></p>
<h2>修改主库、从库 MySQL 配置文件</h2>
<p>1、Master</p>
<p><code>vim /etc/my.cnf</code></p>
<pre><code>datadir=/var/lib/mysql
server-id=1
log-bin=mysql-bin
</code></pre>
<p>2、Slave:</p>
<p><code>vim /etc/my.cnf</code></p>
<pre><code>server-id=2
datadir=/var/lib/mysql
</code></pre>
<h2>安装 XtraBackup</h2>
<h3>1、添加源</h3>
<p><code>yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm</code></p>
<p>检查是否添加成功:</p>
<p><code>yum list | grep percona</code></p>
<p>如果执行正确,其输出信息通常类似:</p>
<pre><code>percona-release.x86_64 0.0-1 installed
...
Percona-Server-client-51.x86_64 5.1.47-rel11.1.51.rhel5 percona
Percona-Server-devel-51.x86_64 5.1.47-rel11.1.51.rhel5 percona
Percona-Server-server-51.x86_64 5.1.47-rel11.1.51.rhel5 percona
Percona-Server-shared-51.x86_64 5.1.47-rel11.1.51.rhel5 percona
Percona-Server-test-51.x86_64 5.1.47-rel11.1.51.rhel5 percona
...
xtrabackup.x86_64 1.2-22.rhel5 percona
</code></pre>
<h3>2、安装 xtrabackup</h3>
<p><code>yum install percona-xtrabackup</code></p>
<h2>创建备份</h2>
<p><code>innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/</code></p>
<p>如果执行正确,其输出信息通常类似:</p>
<pre><code>innobackupex: Backup created in directory '/path/to/BACKUP-DIR/2015-03-03_00-00-09'
innobackupex: MySQL binlog position: filename 'mysql-bin.000003', position 1946
111225 00:00:53 innobackupex: completed OK!
</code></pre>
<p>备份时,innobackupex 会调用 xtrabackup 备份 InnoDB 表的数据,并且会复制 MyISAM, MERGE,CSV 和 ARCHIVE 表的表定义文件(.frm 文件)、数据文件。同时还会备份触发器和数据库配置信息相关的文件。这些文件将会保存在指定备份目录中一个以时间戳命名的目录下。</p>
<h2>准备备份</h2>
<p>一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态。</p>
<p><code>innobackupex --apply-log /path/to/BACKUP-DIR</code></p>
<p>如果执行正确,其最后输出的几行信息通常如下:</p>
<pre><code>xtrabackup: starting shutdown with innodb_fast_shutdown = 1
120407 9:01:36 InnoDB: Starting shutdown...
120407 9:01:40 InnoDB: Shutdown completed; log sequence number 92036620
120407 09:01:40 innobackupex: completed OK!
</code></pre>
<p>在实现“准备”的过程中,innobackupex 通常还可以使用 --use-memory 选项来指定其可以使用的内存的大小,默认通常为 100M。如果有足够的内存可用,可以多划分一些内存给 prepare 的过程,以提高其完成速度。</p>
<h2>恢复备份</h2>
<p>将数据复制到从服务器上:<br><code>scp -r /path/to/BACKUP-DIR root@slave_host:/data/</code></p>
<p>在从服务器中恢复备份数据:<br><code>innobackupex --copy-back /path/to/BACKUP-DIR</code></p>
<p>如果服务器剩余空间不足,你可以使用 <code>--move-back</code> 替换掉 <code>--copy-back</code>。</p>
<p>如果执行正确,其输出信息的最后几行通常如下:</p>
<pre><code>innobackupex: Starting to copy InnoDB log files
innobackupex: in '/backup/2012-04-07_08-17-03'
innobackupex: back to original InnoDB log directory '/mydata/data'
innobackupex: Finished copying back files.
...
120407 09:36:10 innobackupex: completed OK!
</code></pre>
<h2>启动从库 MySQL,设置主库信息</h2>
<p>当数据恢复至数据目录以后,还需要确保所有数据文件的属主和属组均为正确的用户,如mysql,否则,在启动mysqld之前还需要事先修改数据文件的属主和属组。如:</p>
<p><code>chown -R mysql:mysql /mydata/data/</code></p>
<p>启动从库:</p>
<p><code>/etc/init.d/mysqld start</code></p>
<p>在主库中开设主从用的账号和权限:</p>
<p><code>GRANT REPLICATION SLAVE ON *.* TO 'slave'@'192.168.0.1' IDENTIFIED BY 'slave';</code></p>
<p>查看备份文件 <code>xtrabackup_binlog_info</code> 中的日志文件以及position。</p>
<pre><code>CHANGE MASTER TO
MASTER_HOST='<master_host>',
MASTER_USER='<slave_username>',
MASTER_PASSWORD='<slave_password>',
MASTER_LOG_FILE='<see xtrabackup_binlog_info>',
MASTER_LOG_POS=<see xtrabackup_binlog_info>;
</code></pre>
<p>开启主从同步:</p>
<pre><code>START SLAVE;
</code></pre>
<p>查看从库状态:</p>
<pre><code>SHOW SLAVE STATUS;
</code></pre>
<p>Ps:用 innobackupex 备份数据时,–apply-log 处理过的备份数据里有两个文件说明该备份数据对应的 binlog 的文件名和位置。但有时这俩文件说明的位置可能会不同。<br>
1 对于纯 InnoDB 操作,备份出来的数据中上述两个文件的内容是一致的<br>
2 对于 InnoDB 和非事务存储引擎混合操作,xtrabackup_binlog_info 中所示的 position 应该会比 xtrabackup_pos_innodb 所示的数值大。此时应以 xtrabackup_binlog_info 为准;而后者和 apply-log 时 InnoDB recovery log 中显示的内容是一致的,只针对 InnoDB 这部分数据。</p>
<p>Ps2:启动 MySQL 时,遇到权限问题的解决方法:</p>
<p>报错信息:</p>
<pre><code>150430 14:41:16 InnoDB: Operating system error number 13 in a file operation.
InnoDB: The error means mysqld does not have the access rights to
InnoDB: the directory.
</code></pre>
<p>解决方法:<br><code>chown -R mysql:mysql /home/data/mysql</code><br><code>chcon -R -t mysqld_db_t /home/mysql</code></p>
<p>参考资料:</p>
<p>1、<a rel="nofollow" href="http://www.oschina.net/question/1997575_167330">http://www.oschina.net/question/1997575_167330</a><br>
2、<a rel="nofollow" href="http://www.linuxidc.com/Linux/2012-10/71919.htm">http://www.linuxidc.com/Linux/2012-10/71919.htm</a><br>
3、<a rel="nofollow" href="http://julyclyde.org/?p=403">http://julyclyde.org/?p=403</a></p>
mysqldump 使用备忘
https://segmentfault.com/a/1190000002574759
2015-03-03T15:12:36+08:00
2015-03-03T15:12:36+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<h2>语法</h2>
<h4>导出所有数据库:</h4>
<pre><code>mysqldump -u root -p -A > backupfile.sql
</code></pre>
<h4>导出指定数据库:</h4>
<pre><code>mysqldump -u root -p -B dbName1 dbName2 > backupfile.sql
</code></pre>
<h4>导出指定表:</h4>
<pre><code>mysqldump -u root -p -B dbName tableName1 tableName2 > backupfile.sql
</code></pre>
<h4>只导出表结构:</h4>
<pre><code>mysqldump -u root -p -A -d > backupfile.sql
</code></pre>
<h2>命令示例</h2>
<pre><code>mysqldump -u root -p databaseName tableName -t --insert-ignore -e --max_allowed_packet=2097152 --net_buffer_length=16384 > backupfile.sql;
</code></pre>
<h2>解释:</h2>
<ul>
<li>-A(--all-databases):导出全部数据库;</li>
<li>-B(--databases):导出指定数据库,后边可跟多个参数;</li>
<li>-t(--no-create-info):不导出创表的语句。不加参数是默认导出建表语句(先drop table然后create table);</li>
<li>-d(--no-data):不导出任何数据,只导出数据库表结构;</li>
<li>--insert-ignore:导出的insert语句加上ignore,允许重复执行。默认不会加上ignore;</li>
<li>-e(--extended-insert):使用具有多个VALUES列的INSERT语法。这样使导出文件更小,并加速导入时的速度。默认为打开状态,使用--skip-extended-insert取消选项;</li>
<li>--max_allowed_packet:客户端/服务器之间通信的缓存区的最大大小; </li>
<li>--net_buffer_length:TCP/IP和套接字通信缓冲区大小,创建长度达net_buffer_length的行。</li>
<li>--single-transaction:该选项在导出数据之前提交一个BEGIN SQL语句,BEGIN 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于多版本存储引擎,仅InnoDB。本选项和--lock-tables 选项是互斥的,因为LOCK TABLES 会使任何挂起的事务隐含提交。要想导出大表的话,应结合使用--quick 选项。</li>
</ul>
<h2>注意</h2>
<p>max_allowed_packet 和 net_buffer_length 不能比目标数据库的设定数值大,否则可能出错。</p>
<p>确定目标数据库的参数值的方法:</p>
<pre><code>mysql> show variables like 'max_allowed_packet';
mysql> show variables like 'net_buffer_length';
</code></pre>
<h2>参考</h2>
<ol>
<li><a rel="nofollow" href="http://www.rover12421.com/2013/01/10/mysql-big-data-fast-import-and-export.html">http://www.rover12421.com/2013/01/10/mysql-big-data-fast-import-and-export.html</a></li>
<li><a rel="nofollow" href="http://codingstandards.iteye.com/blog/1522622">http://codingstandards.iteye.com/blog/1522622</a></li>
<li><a rel="nofollow" href="http://segmentfault.com/blog/koy/1190000000621104">http://segmentfault.com/blog/koy/1190000000621104</a></li>
</ol>
iOS 学习参考资料
https://segmentfault.com/a/1190000002573302
2015-03-02T20:53:14+08:00
2015-03-02T20:53:14+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
5
<h2>编程语言</h2>
<p><a rel="nofollow" href="http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html">Programming with Objective-C: About Objective-C</a> : Apple 撰写的一份关于 Objective-C 2.0 的一份文档,这也算是学习 iOS/Mac 开发必读的一份文档,记得我当初看的时候是叫做 The Objective-C Programming Language。</p>
<p><a rel="nofollow" href="http://cocoadevcentral.com/d/learn_objectivec/">Learn Objective-C</a> :这也是广受推荐的一份文档,短小精练,适合入门。</p>
<p><a rel="nofollow" href="http://www.amazon.com/Programming-Objective-C-Edition-Developers-Library/dp/0321811909">Programming in Objective-C 2.0</a> 原书已经出到第四版了,建议阅读原版,中文版是根据第二版翻译的。此书比较适合入门,它甚至涵盖了 C 语言一些知识。而不像《Objective-C基础教程》直接就进入 Objective-C 及面向对象的一些思想。</p>
<p><a rel="nofollow" href="http://book.douban.com/subject/19962787/">Objective-C编程</a>(英文名:Objective-C Programming: The Big Nerd Ranch Guide):有中文的,翻一翻,照着书,把代码在 Xcode 上敲一遍,编译下看看结果,也可以对代码做些修改,看会不会报错,看会不会得到不同的结果,其实编程就是这样学的,慢慢地就入门了。看完这本书,对 Objective-C 的语法有个大概的了解即可。另外此书的英文版已经出到第 2 版了,如果英语能力不错的,推荐看第 2 版,请点击<a rel="nofollow" href="http://www.bignerdranch.com/we-write/objective-c-programming/">这里</a>。</p>
<h2>iOS 开发</h2>
<p><a rel="nofollow" href="https://developer.apple.com/library/ios/#referencelibrary/GettingStarted/RoadMapiOSCh/index.html#//apple_ref/doc/uid/TP40012668">马上着手开发 iOS 应用程序</a>:苹果官方入门资料,也有的<a rel="nofollow" href="https://developer.apple.com/library/ios/#referencelibrary/GettingStarted/RoadMapiOS/index.html">英文版</a>。这个教程是教你写一个 TodoList 的 app,无需其它准备工作,你可以直接开始,照着教程一步一步做,不需要理解每一步到底是为什么,这是为了让你对 iOS 开发有个大概的认识,也可以让你快速建立对 iOS 开发的兴趣和信心。</p>
<p><a rel="nofollow" href="https://developer.apple.com/library/ios/navigation/">iOS Developer Library</a>:官方的文档库,也是最靠谱的资料了,在 Xcode 中也可以下载后直接查阅。</p>
<p><a rel="nofollow" href="http://www.amazon.com/Beginning-iOS-Development-Exploring-SDK/dp/1430245123">Beginning iOS 6 Development: Exploring the iOS SDK</a> :这个书算是用得比较多的一本了,当初我也是看着这本边学边做。且作者也比较勤快,基本跟随 iOS 更新的步伐,每年修订。当时我看的是 iOS 5 的版本,也建议任何学习资料要看要 iOS 5 以后版本的,因为其引入了 ARC,在内存管理方面和以前的方式有很大的不同。</p>
<p><a rel="nofollow" href="http://www.amazon.com/iOS-Programming-Ranch-Guide-Guides/dp/0321821521">iOS Programming: The Big Nerd Ranch Guide</a>:如果你想对 iOS 开发有个深入、系统地了解,可以看看这本书。比起上面那本这本涉及的面会稍微广些,建议辅助用。</p>
<p><a rel="nofollow" href="http://www.raywenderlich.com/store/ios-apprentice">Ray Wenderlich 的「The iOS Apprentice」教程</a>:目前最新版是第 3 版,质量上乘,包含 Objective-C 和 Swift 的教程,手把手教你写 4 个 app。</p>
<h2>视频教程</h2>
<p><a rel="nofollow" href="http://open.163.com/special/opencourse/ios7.html">斯坦福大学公开课:iOS 7应用开发</a>:适用于iOS7。本课程介绍了使用Xcode5建造iPhone平台上的应用程序所需的工具和应用程序接口;使用多点触控技术,为手机等终端设计用户互交界面等技术进行面向对象的设计。其他主题包括:内核动画、bonjour网络、移动终端电量管理和性能测评。此外 iTunes 上的英文原版见<a rel="nofollow" href="https://itunes.apple.com/us/course/developing-ios-7-apps-for/id733644550">这里</a>。</p>
<p><a rel="nofollow" href="http://bitfountain.io/courses/the-complete-ios-7-course-learn-by-building-14-apps">The Complete iOS 7 Course - Learn by Building 14 Apps</a>:很不错的课程,本来是收费的教程,貌似在用 Swift 重写,所以把 oc 的这套免费了。</p>
<p><a rel="nofollow" href="https://designcode.io/">Design+Code: Learn iOS design and Xcode</a>:这套教程的价格目前是 $50,非常超值,而且还可以得到一个 Sketch 的 8 折优惠码,一个 Ember 的 7 折优惠码。这套教程的好处在于,你不仅学会了用 Objective-C 开发一个 app,同时还学会了用 Sketch 设计一个 app,里面还包含了 Swift 的教程。</p>
<h2>开源项目</h2>
<p>Github 优秀开源项目收集:<a rel="nofollow" href="http://github.ibireme.com/github/list/ios/">http://github.ibireme.com/github/list/ios/</a><br>
code4app 上的代码资源:<a rel="nofollow" href="http://code4app.com/resource">http://code4app.com/resource</a></p>
<h2>优秀博客</h2>
<p>objc中国:<a rel="nofollow" href="http://objccn.io/">http://objccn.io/</a><br>
大猫的意淫笔记:<a rel="nofollow" href="http://bigc.at/">http://bigc.at/</a><br>
M了个J:<a rel="nofollow" href="http://www.cnblogs.com/mjios">http://www.cnblogs.com/mjios</a><br>
唐巧技术博客—— ios开发、java开发等:<a rel="nofollow" href="http://blog.devtang.com">http://blog.devtang.com</a><br>
董宝君的iOS技术博客:<a rel="nofollow" href="http://blog.devdong.com/">http://blog.devdong.com/</a><br>
图拉鼎的博客:<a rel="nofollow" href="http://imtx.me/">http://imtx.me/</a><br>
ygm900:<a rel="nofollow" href="http://www.cnblogs.com/ygm900/">http://www.cnblogs.com/ygm900/</a><br>
雨中泪雪人的博客:<a rel="nofollow" href="http://blog.sina.com.cn/yzykhq">http://blog.sina.com.cn/yzykhq</a><br>
EntLib.net 技术分享平台:<a rel="nofollow" href="http://www.entlib.net/?cat=95">http://www.entlib.net/?cat=95</a><br>
Yaski的iPhone博客:<a rel="nofollow" href="http://www.cnblogs.com/yaski/">http://www.cnblogs.com/yaski/</a><br>
AppCoda - Learn iOS Programming and Build iPhone App:<a rel="nofollow" href="http://www.appcoda.com/">http://www.appcoda.com/</a><br>
梦维:<a rel="nofollow" href="http://www.dreamingwish.com/">http://www.dreamingwish.com/</a><br>
RannieR的技术博客:<a rel="nofollow" href="http://blog.csdn.net/ran0809/article/category/1569165">http://blog.csdn.net/ran0809/article/category/1569165</a><br>
丸子的iOS开发经验:<a rel="nofollow" href="http://iaiai.iteye.com/category/202253">http://iaiai.iteye.com/category/202253</a><br>
邓映山的博客:<a rel="nofollow" href="http://www.objcer.com/">http://www.objcer.com/</a><br>
王德康的空间:<a rel="nofollow" href="http://my.oschina.net/wangdk/blog?catalog=375448">http://my.oschina.net/wangdk/blog?catalog=375448</a><br>
唐韧 Ryan's zone In Android & iOS:<a rel="nofollow" href="http://blog.csdn.net/tangren03/article/category/1073221">http://blog.csdn.net/tangren03/article/category/1073221</a><br>
MAGICALBOY:<a rel="nofollow" href="http://magicalboy.com/">http://magicalboy.com/</a><br>
菜鸟学iOS的笔记 - 新风作浪的博客专栏:<a rel="nofollow" href="http://blog.csdn.net/duxinfeng2010/article/category/1155790">http://blog.csdn.net/duxinfeng2010/article/category/1155790</a><br>
阿福的专栏:<a rel="nofollow" href="http://blog.csdn.net/lizhongfu2013">http://blog.csdn.net/lizhongfu2013</a><br>
iOS-Coding的博客:<a rel="nofollow" href="http://blog.sina.com.cn/p709723778">http://blog.sina.com.cn/p709723778</a><br>
破船之家:<a rel="nofollow" href="http://beyondvincent.com/">http://beyondvincent.com/</a><br>
iOS分享网——分享iOS开发学习资料(视频电子书文章源码):<a rel="nofollow" href="http://iosshare.cn/">http://iosshare.cn/</a><br>
songrotek的专栏:<a rel="nofollow" href="http://blog.csdn.net/songrotek">http://blog.csdn.net/songrotek</a><br>
容芳志专栏:<a rel="nofollow" href="http://blog.csdn.net/totogo2010">http://blog.csdn.net/totogo2010</a><br>
fengsh998的专栏:<a rel="nofollow" href="http://blog.csdn.net/fengsh998/article/category/1222508">http://blog.csdn.net/fengsh998/article/category/1222508</a></p>
<h2>参考来源</h2>
<ol>
<li><a rel="nofollow" href="http://www.jianshu.com/p/KSuDqb">http://www.jianshu.com/p/KSuDqb</a></li>
<li><a rel="nofollow" href="http://readful.com/post/101914515826/0-ios">http://readful.com/post/101914515826/0-ios</a></li>
<li><a rel="nofollow" href="http://ruziniu0510.blog.163.com/blog/static/86050179201393045738887/">http://ruziniu0510.blog.163.com/blog/static/86050179201393045738887/</a></li>
</ol>
开发 WebAPP 的几个前端框架
https://segmentfault.com/a/1190000002571760
2015-03-01T23:35:23+08:00
2015-03-01T23:35:23+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
1
<p><a rel="nofollow" href="http://mobileangularui.com/">http://mobileangularui.com/</a></p>
<p><a rel="nofollow" href="http://ionicframework.com/">http://ionicframework.com/</a></p>
<p><a rel="nofollow" href="http://www.idangero.us/framework7/">http://www.idangero.us/framework7/</a> (中文文档:<a rel="nofollow" href="http://framework7.taobao.org/">http://framework7.taobao.org/</a>)</p>
<p><a rel="nofollow" href="http://amazeui.org/">http://amazeui.org/</a></p>
服务器配置记录「不断更新」
https://segmentfault.com/a/1190000002523631
2015-01-30T00:17:29+08:00
2015-01-30T00:17:29+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<h2>安装必备软件包</h2>
<p>执行以下命令安装必备软件包:<br><code>yum -y install wget vim sudo screen crontabs ntpdate</code></p>
<h2>设置自动校时</h2>
<p>设置每早 6:00 对时,编辑计划任务文件 /etc/crontab,添加一行:<br><code>0 6 * * * root /usr/sbin/ntpdate time.nist.gov > /dev/null</code></p>
<blockquote>
<p>注:在命令的最后加上 > /dev/null 可以隐藏命令输出的信息(但不包括错误信息),这可以让你不会在每次对时后都收到一封邮件,而一旦出现错误时你仍可知晓。如果添加 &> /dev/null 则会隐藏所有输出,包括错误信息。</p>
</blockquote>
<h2>启动计划任务</h2>
<p><code>service crond start</code></p>
<h2>设立 IP 白名单</h2>
<p><code>vim /etc/hosts.deny</code><br>
添加<br><code>sshd:ALL</code></p>
<p><code>vim /etc/hosts.allow</code><br>
添加<br><code>sshd:8.8.8.8:allow #其中 8.8.8.8 修改为允许的 IP</code></p>
<h2>Memcache 启动方法</h2>
<p><code>memcached -d -p 11211 -u memcached -m 1024 -c 10240 -P /var/run/memcached.pid -l 127.0.0.1</code></p>
<p>其中:<br>
-d 代表启动一个守护进程;<br>
-l 绑定的 IP 地址,默认所有都允许,有安全隐患。若设置为 127.0.0.1 就只能本机访问;<br>
-u 代表运行的用户,例如 root;<br>
-p 代表 Memcache 监听的端口,默认是 11211;<br>
-m 代表允许占用的内存大小,默认为 64,单位为 Mb;<br>
-c 代表是最大运行的并发连接数,默认是 1024;<br>
-P 代表保存 Memcache 的 pid 文件;<br>
-v 提示信息(在事件循环中打印错误/警告信息。)<br>
-vv 详细信息(还打印客户端命令/响应)<br>
-vvv 超详细信息(还打印内部状态的变化)</p>
CentOS LNMP 环境搭建记录
https://segmentfault.com/a/1190000002523612
2015-01-30T00:04:30+08:00
2015-01-30T00:04:30+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
1
<p>*仅供参考,如有不当之处,欢迎批评指正。以下安装过程以 CentOS 5.* 系列为例 *</p>
<h2>准备需要的源</h2>
<h4>1、添加 EPEL 源:</h4>
<p>项目地址:<a rel="nofollow" href="http://fedoraproject.org/wiki/EPEL">http://fedoraproject.org/wiki/EPEL</a><br>
安装步骤:</p>
<pre><code>//根据 CentOS 版本不同,下方地址也不同
wget http://ftp.sjtu.edu.cn/fedora/epel/5/i386/epel-release-5-4.noarch.rpm
//安装
rpm -ivh epel-release-5-4.noarch.rpm
</code></pre>
<h4>2、添加 Remi 源:</h4>
<p>项目地址:<a rel="nofollow" href="http://rpms.famillecollet.com/">http://rpms.famillecollet.com/</a><br>
安装步骤:</p>
<pre><code>//根据 CentOS 版本不同,下方地址也不同
wget http://rpms.famillecollet.com/enterprise/remi-release-5.rpm
//安装
rpm -ivh remi-release-5.rpm
//查看 Remi 源的软件列表
yum --disablerepo=* --enablerepo=remi,remi-php55,remi-test list available | less
</code></pre>
<h4>3、添加 Nginx 官方源:</h4>
<p>项目地址:<a rel="nofollow" href="http://nginx.org/en/linux_packages.html#stable">http://nginx.org/en/linux_packages.html#stable</a><br>
安装步骤:</p>
<pre><code>//根据 CentOS 版本不同,下方地址也不同
wget http://nginx.org/packages/centos/5/noarch/RPMS/nginx-release-centos-5-0.el5.ngx.noarch.rpm
//安装
rpm -ivh nginx-release-centos-5-0.el5.ngx.noarch.rpm
</code></pre>
<h4>4、添加 MySQL 官方源:</h4>
<p>项目地址:<a rel="nofollow" href="https://dev.mysql.com/downloads/repo/yum/">https://dev.mysql.com/downloads/repo/yum/</a><br>
安装步骤:</p>
<pre><code>//根据 CentOS 版本不同,下方地址也不同
wget https://dev.mysql.com/get/mysql-community-release-el5-5.noarch.rpm --no-check-certificate
//安装
rpm -ivh mysql-community-release-el5-5.noarch.rpm
//查看 MySQL 源的软件列表
yum --disablerepo=* --enablerepo=mysql56-community list available | less
</code></pre>
<h2>安装</h2>
<h4>安装 PHP</h4>
<pre><code>yum --enablerepo=remi,remi-php56,epel install php
</code></pre>
<h4>安装 PHP 相关扩展</h4>
<pre><code>yum --enablerepo=remi,remi-php56,epel install php-gd php-mcrypt php-mbstring php-mysql php-pecl-memcached php-fpm
</code></pre>
<h4>安装 Nginx</h4>
<pre><code>yum --disablerepo=* --enablerepo=nginx install nginx
</code></pre>
<h4>安装 MySQL</h4>
<pre><code>yum --disablerepo=* --enablerepo=mysql56-community install mysql mysql-server
</code></pre>
<h2>相关配置</h2>
<h4>MySQL 参考配置</h4>
<pre><code>[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
character-set-server=utf8
skip-name-resolve
slow_query_log=1
slow_query_log_file=/var/log/mysql/slowquery.log
log-queries-not-using-indexes=on #记录没有使用索引的查询
server-id=3
log-bin=mysql-bin
expire_logs_days = 10
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used (fedora >= 15).
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mysqld according to the
# instructions in http://fedoraproject.org/wiki/Systemd
user=mysql
# Semisynchronous Replication
# http://dev.mysql.com/doc/refman/5.5/en/replication-semisync.html
# uncomment next line on MASTER
;plugin-load=rpl_semi_sync_master=semisync_master.so
# uncomment next line on SLAVE
;plugin-load=rpl_semi_sync_slave=semisync_slave.so
# Others options for Semisynchronous Replication
;rpl_semi_sync_master_enabled=1
;rpl_semi_sync_master_timeout=10
;rpl_semi_sync_slave_enabled=1
# http://dev.mysql.com/doc/refman/5.5/en/performance-schema.html
;performance_schema
#innodb
innodb_file_per_table=1
innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_size=1G
innodb_log_buffer_size=16M
innodb_log_file_size=128M
back_log=100
max_connections=1200
max_allowed_packet=2M
max_heap_table_size=64M
sort_buffer_size=16M
join_buffer_size=16M
thread_cache_size=16
tmp_table_size=64M
key_buffer_size=64M
read_rnd_buffer_size=16M
bulk_insert_buffer_size=128M
myisam_sort_buffer_size=128M
myisam_recover
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
</code></pre>
<h4>Nginx PATHINFO 参考配置片段</h4>
<pre><code> server {
listen 80;
server_name top.qimai.net;
root /usr/share/nginx/html/appstore;
location / {
root /usr/share/nginx/html/appstore;
index index.php index.html index.htm;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ [^/]\.php(/|$) {
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
}
}
</code></pre>
使用 OpCache 提升 PHP 性能
https://segmentfault.com/a/1190000002523558
2015-01-29T23:38:50+08:00
2015-01-29T23:38:50+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
8
<p>OpCache 通过对 opcode 的缓存和优化来提升 PHP 执行速度。在 PHP 5.5、5.6 版本中 OpCache 已内建,编译安装时使用 --enable-opcache 即可。PHP 5.2 - 5.4 也可手动安装。</p>
<h2>项目主页</h2>
<p><a rel="nofollow" href="http://pecl.php.net/package/ZendOpcache">http://pecl.php.net/package/ZendOpcache</a></p>
<h2>开启方法</h2>
<p>修改 php.ini 文件<code>sudo vim /etc/php.ini</code></p>
<p>在文件最后面加入:</p>
<pre><code>; 开关打开
opcache.enable=1
; 可用内存, 酌情而定, 单位 megabytes
opcache.memory_consumption=256
; 最大缓存的文件数目, 命中率不到 100% 的话, 可以试着提高这个值
opcache.max_accelerated_files=5000
; Opcache 会在一定时间内去检查文件的修改时间, 这里设置检查的时间周期, 默认为 2, 单位为秒
opcache.revalidate_freq=240
; interned string 的内存大小, 也可调
opcache.interned_strings_buffer=8
; 是否快速关闭, 打开后在PHP Request Shutdown的时候回收内存的速度会提高
opcache.fast_shutdown=1
; 不保存文件/函数的注释
opcache.save_comments=0
</code></pre>
<h2>检查安装:</h2>
<pre><code> php -v
PHP 5.5.3-1ubuntu2.2 (cli) (built: Feb 28 2014 20:06:05)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
with Zend OPcache v7.0.3-dev, Copyright (c) 1999-2013, by Zend Technologies
</code></pre>
<h2>重启服务</h2>
<pre><code>sudo /etc/init.d/php-fpm restart
sudo /etc/init.d/nginx restart
</code></pre>
<h2>查看效果</h2>
<ul>
<li>拥有漂亮的图形化界面的项目 : <a rel="nofollow" href="https://github.com/PeeHaa/OpCacheGUI">https://github.com/PeeHaa/OpCacheGUI</a>
</li>
<li>单文件, 方便部署的项目: <a rel="nofollow" href="https://github.com/rlerdorf/opcache-status">https://github.com/rlerdorf/opcache-status</a>
</li>
</ul>
<h2>小提示</h2>
<p>如果在更新代码之后,发现没有执行的还是旧代码,可使用函数 <code>opcache_reset()</code> 来清除缓存。该函数将重置整个字节码缓存。 在调用 opcache_reset() 之后,所有的脚本将会重新载入并且在下次被点击的时候重新解析。</p>
<h2>参考:</h2>
<blockquote>
<p>1、使用 OpCache 提升 PHP 5.5+ 程序性能:<a rel="nofollow" href="https://phphub.org/topics/301">https://phphub.org/topics/301</a><br>
2、ZendOpcache 官方下载:<a rel="nofollow" href="http://pecl.php.net/package/ZendOpcache">http://pecl.php.net/package/ZendOpcache</a><br>
3、一个关于Zend O+的小分享:<a rel="nofollow" href="http://www.laruence.com/2013/11/11/2928.html">http://www.laruence.com/2013/11/11/2928.html</a><br>
4、OCP -Opcache Control Panel:<a rel="nofollow" href="https://gist.github.com/ck-on/4959032">https://gist.github.com/ck-on/4959032</a><br>
5、PHP WIKI 关于整合 ZendOpcache 进入发行版的讨论:<a rel="nofollow" href="https://wiki.php.net/rfc/optimizerplus">https://wiki.php.net/rfc/optimizerplus</a></p>
</blockquote>
Host '*' is blocked because of many connection errors.
https://segmentfault.com/a/1190000002487599
2015-01-14T23:12:21+08:00
2015-01-14T23:12:21+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<p>某天,连接服务器数据库时,提示:Host '*' is blocked because of many connection errors. Unblock with 'mysqladmin flush-hosts'</p>
<p>解决方法:<br>
在目标服务器,执行<code>mysqladmin -uroot -p flush-hosts</code></p>
MemcacheQ 的安装与使用
https://segmentfault.com/a/1190000000498922
2014-05-08T22:09:06+08:00
2014-05-08T22:09:06+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<p><strong>1、安装libevent</strong></p>
<p>官网:<a rel="nofollow" href="http://www.libevent.org/">http://www.libevent.org/</a></p>
<pre><code>$ wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz --no-check-certificate
$ tar -zxvf libevent-2.0.21-stable.tar.gz
$ cd libevent-2.0.21-stable
$ ./configure --prefix=/usr/local/libevent
$ sudo make && make install
</code></pre>
<p><strong>2、安装 BerkeleyDB</strong></p>
<p>官网:<a rel="nofollow" href="http://www.oracle.com/technetwork/products/berkeleydb/downloads/index.html">http://www.oracle.com/technetwork/products/berkeleydb/downloads/index.html</a>(下载需要登录)</p>
<p>安装:</p>
<pre><code>$ wget http://download.oracle.com/berkeley-db/db-6.0.30.tar.gz
$ tar -zxvf db-6.0.30.tar.gz (根据自身的情况解压到目录)
$ cd db-6.0.30/build_unix
$ ../dist/configure --prefix=/usr/local/berkeleyDB
$ sudo make && make install
</code></pre>
<p>安装完成之后:</p>
<pre><code>$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/libevent/lib:/usr/local/berkeleyDB/lib
</code></pre>
<p>或者:</p>
<pre><code>$ vim /etc/ld.so.conf
</code></pre>
<p>添加:</p>
<pre><code>/usr/local/libevent/lib
/usr/local/berkeleyDB/lib
</code></pre>
<p>并执行:</p>
<pre><code>$ /sbin/ldconfig
</code></pre>
<p><strong>3、安装 MemcacheQ</strong></p>
<p>官网:<a rel="nofollow" href="http://memcachedb.org/memcacheq/">http://memcachedb.org/memcacheq/</a></p>
<pre><code>$ wget https://memcacheq.googlecode.com/files/memcacheq-0.2.0.tar.gz
$ tar -zxvf memcacheq-0.2.0.tar.gz
$ cd memcacheq-0.2.0
$ ./configure --prefix=/usr/local/memcacheq --enable-threads --with-libevent=/usr/local/libevent --with-bdb=/usr/local/berkeleyDB
$ sudo make && make install
</code></pre>
<p>测试是否安装成功:</p>
<pre><code>/usr/local/memcacheq/bin/memcacheq -h
</code></pre>
<p><strong>4、启动服务</strong></p>
<p>建立相关目录:</p>
<pre><code>mkdir -p 755 /var/memcacheq/logs/
mkdir -p 755 /var/memcacheq/data/
</code></pre>
<p>启动服务:</p>
<pre><code>/usr/local/memcacheq/bin/memcacheq -d -r -uroot -p11212 -H /var/memcacheq/data -N -R -v -L 1024 -B 1024 > /var/memcacheq/logs/mq_error.log 2>&1
</code></pre>
<p>参数说明:</p>
<blockquote>
<p>-d : 以后台服务方式运行<br>
-l : 设置监听地址及端口(默认是22201)<br>
-A : 数据页大小<br>
-H : 数据保存目录<br>
-B : 队列中每条数据的最大长度(字节)<br>
-N : 使用内存缓冲方式保存数据至磁盘,从而获得极高性能。若无此参数,性能会很差<br>
-R : 自动清理过期的日志<br>
-u : 设置memcacheq进程账号<br>
-L :日志缓存大小(默认是32K,1024表示1024K)</p>
</blockquote>
<p>添加到开机启动:</p>
<pre><code>vim /etc/rc.local
</code></pre>
<p>添加:</p>
<pre><code>/usr/local/memcacheq/bin/memcacheq -d -r -uroot -p11212 -H /var/memcacheq/data -N -R -v -L 1024 -B 1024 > /var/memcacheq/logs/mq_error.log 2>&1
</code></pre>
<p><strong>5、使用 PHP 连接</strong></p>
<pre><code><?php
$memcache_obj = new Memcache;
$memcache_obj->connect('127.0.0.1', 11212);
$memcache_obj->set('pushtask','38a7d8a504d69d1e2ac843b5804c04',0,0);
$memcache_obj->close();
?>
<?php
$memcache_obj = new Memcache;
$memcache_obj->connect('127.0.0.1', 11212);
$task = $memcache_obj->get('pushtask');
//do your task here
...
$memcache_obj->close();
?>
</code></pre>
<p><strong>6、使用命令行连接</strong></p>
<p>连接:</p>
<pre><code>telnet 127.0.0.1 11212
</code></pre>
<p>添加:</p>
<pre><code>格式:
set <queue name> <flags> 0 <message_len>
<put your message body here>
STORED
示例:
set test_queue 0 0 6
abcdef
STORED
</code></pre>
<p>获取:</p>
<pre><code>格式:
get <queue name>
VALUE <queue name> <flags> <message_len>
<your message body will come here>
END
示例:
get test_queue
VALUE test_queue 0 13
first_message
END
</code></pre>
<p>查看队列:</p>
<pre><code>stats queue
STAT test_queue 20/10 #表示队列test_queue里面有20条信息,读取了10条
END
</code></pre>
<p>删除整个队列:</p>
<pre><code>格式:
delete <queue name>
示例:
delete test_queue
DELETED
</code></pre>
Gearman 的安装和使用
https://segmentfault.com/a/1190000000494087
2014-05-05T21:29:25+08:00
2014-05-05T21:29:25+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
5
<p><strong>1、安装 Gearman</strong></p>
<p>首先,下载 Gearman 守护程序 gearmand 的最新源代码(<a rel="nofollow" href="https://launchpad.net/gearmand">地址</a>),解压缩这个 tarball,并安装(安装需要 root 权限)。</p>
<pre><code>$ wget https://launchpad.net/gearmand/1.2/1.1.12/+download/gearmand-1.1.12.tar.gz
$ tar xvzf gearmand-1.1.12.tar.gz
$ cd gearmand-1.1.12
$ ./configure
$ make
$ sudo make install
</code></pre>
<p>如果 configure 时,提示 configure: error: could not find boost,则需要先安装 boost library:</p>
<pre><code>$ yum install boost-devel
</code></pre>
<p>安装 gearmand 后,构建 PHP 扩展。您可以从 PECL 获取这个 tarball(<a rel="nofollow" href="http://pecl.php.net/package/gearman">地址</a>)。</p>
<pre><code>$ wget http://pecl.php.net/get/gearman-1.1.2.tgz
$ tar xvzf gearman-1.1.2.tgz
$ cd gearman-1.1.2
</code></pre>
<p>有了这些代码后,就可以开始构建扩展了:</p>
<pre><code>$ phpize
$ ./configure
$ make
$ make install
</code></pre>
<p>如果 configure 时提示错误:configure: error: C preprocessor "/lib/cpp" fails sanity check,则需要安装 c++ 编译器相关 package:</p>
<pre><code>yum install glibc-headers
yum install gcc-c++
yum install kernel-headers
</code></pre>
<p>这个 Gearman 守护程序通常被安装在 /usr/sbin。可以从命令行直接启动此守护程序,也可以将这个守护程序添加到启动配置中,以便在机器每次重启时就可以启动这个守护程序。<br>
接下来,需要安装 Gearman 扩展。打开 php.ini 文件(可以通过 php --ini 命令快速找到这个文件),然后添加代码行 extension = gearman.so:</p>
<pre><code>$ php --ini //Loaded Configuration File: /etc/php/php.ini
$ vi /etc/php/php.ini
...
extension = gearman.so
</code></pre>
<p>保存此文件。要想验证扩展是否启用,请运行 php --info,然后查找 Gearman:</p>
<pre><code>$ php --info | grep gearman
</code></pre>
<p>此外,还可以用一个 PHP 代码片段来验证构建和安装是否得当。将这个小应用程序保存到 verify_gearman.php:</p>
<pre><code><?php
print gearman_version() . "\n";
?>
</code></pre>
<p>接下来,从命令行运行此程序:</p>
<pre><code>$ php verify_gearman.php //0.10
</code></pre>
<p>如果这个版本号与之前构建和安装的 Gearman 库的版本号相匹配,那么系统就已准备好了。</p>
<p>然后启动这个 agent,即 Gearman 守护程序:</p>
<pre><code>$ gearmand -d
</code></pre>
<p><strong>2、从 PHP 使用 Gearman</strong></p>
<p>用 PHP 编写的一个 Gearman worker。将这些代码保存在一个名为 worker.php 的文件中。</p>
<pre><code><?php
$worker= new GearmanWorker();
$worker->addServer();
$worker->addFunction("title", "title_function");
while ($worker->work());
function title_function($job){
return ucwords(strtolower($job->workload()));
}
?>
</code></pre>
<p>用 PHP 编写的一个 producer,或 client。将此代码保存在一个名为 client.php 的文件内。</p>
<pre><code><?php
$client= new GearmanClient();
$client->addServer();
print $client->do("title", "AlL THE World's a sTagE");
print "\n";
?>
</code></pre>
<p>现在,可以用如下的命令行连接客户机与 worker 了:</p>
<pre><code>$ php worker.php &
$ php client.php
All The World's A Stage
$ jobs
[3]+ Running php worker.php &
</code></pre>
<p>来源于:<a rel="nofollow" href="http://www.ibm.com/developerworks/cn/opensource/os-php-gearman/">用 Gearman 分发 PHP 应用程序的工作负载</a></p>
常用 Linux 命令备忘
https://segmentfault.com/a/1190000000494069
2014-05-05T21:11:51+08:00
2014-05-05T21:11:51+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
3
<p>1、查看 centos 发行版本</p>
<pre><code>cat /etc/redhat-release
</code></pre>
<p>2、查看处理器位数</p>
<pre><code>uname -a
</code></pre>
<p>3、查看文件夹大小</p>
<pre><code>du -sh
</code></pre>
<p>4、以 root 身份运行上条命令</p>
<pre><code>sudo !!
</code></pre>
<p>5、列出目录里最大的十个文件</p>
<pre><code>du -s * | sort -n | tail
</code></pre>
<p>6、时间戳转换为时间</p>
<pre><code>date -d@1234567890
</code></pre>
<p>7、查看端口及进程</p>
<pre><code>netstat -nlp |grep LISTEN //查看当前所有监听端口
netstat -nlp |grep 80 //查看所有80端口使用情况
</code></pre>
<p>8、检查用户登录记录</p>
<pre><code>more /var/log/secure
who /var/log/wtmp
</code></pre>
<p>9、查看所有的进程</p>
<pre><code>ps -ef //常与grep搭配使用:ps -ef | grep
</code></pre>
<p>10、查看所有用户的 crontab 任务</p>
<pre><code>cd /var/spool/cron
cat demousername
</code></pre>
<p>11、让进程转入后台</p>
<pre><code>Ctrl + z
</code></pre>
<p>12、将进程转到前台</p>
<pre><code>fg
</code></pre>
<p>13、产生随机的十六进制数,其中n是字符数</p>
<pre><code>openssl rand -hex n
</code></pre>
<p>14、SSH debug 模式</p>
<pre><code>ssh -vvv user@ip_address
</code></pre>
<p>15、查看是否有 MySQL 端口</p>
<pre><code>netstat -ntlp | grep 3306
</code></pre>
<p>16、统计历史上使用的命令行的次数,并排出前十名</p>
<pre><code>history | awk '{CMD[$2]++;count++;}END { for (a in CMD)\
print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" \
| column -c3 -s " " -t | sort -nr | nl | head -n10</code></pre>
<p>17、查看进程树</p>
<pre><code>ps aufx
</code></pre>
Nginx 下 Laravel 的安装
https://segmentfault.com/a/1190000000494042
2014-05-05T20:54:40+08:00
2014-05-05T20:54:40+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
2
<p>1、安装Composer</p>
<pre><code>$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer
</code></pre>
<p>2、安装Laravel</p>
<pre><code>composer create-project laravel/laravel your-project-name
</code></pre>
<p>3、为 app/storage 目录下的文件设置写权限</p>
<p>4、配置 nginx</p>
<pre><code>location /laravel/public/ {
try_files $uri $uri/ /laravel/public/index.php?$args;
}
</code></pre>
Linux 下通过 phpize 安装 PHP 扩展 memcache
https://segmentfault.com/a/1190000000494038
2014-05-05T20:51:56+08:00
2014-05-05T20:51:56+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
1
<p>1、下载并解压 memcache 扩展文件</p>
<pre><code>wget -c http://pecl.php.net/get/memcache-3.0.8.tgz
tar xzvf memcache-3.0.8.tgz
cd memcache-3.0.8
</code></pre>
<p>2、执行 phpize 扩展安装程序(具体路径需根据自己系统环境修改)</p>
<pre><code>/usr/local/php/bin/phpize
</code></pre>
<p>3、编译安装 memcache</p>
<pre><code>./configure --enable-memcache --with-php-config=/usr/local/php/bin/php-config --with-zlib-dir
make && make install
</code></pre>
<p>4、修改 php.ini,添加扩展</p>
<pre><code>extension = "memcache.so"
</code></pre>
<blockquote>
<p>参考:<br>
1、PHP官方文档-phpize:<a rel="nofollow" href="http://www.php.net/manual/zh/install.pecl.phpize.php">http://www.php.net/manual/zh/install.pecl.phpize.php</a><br>
2、PECL memcache扩展下载:<a rel="nofollow" href="http://pecl.php.net/package/memcache">http://pecl.php.net/package/memcache</a></p>
</blockquote>
Linux 下建立 del 函数防止错删文件
https://segmentfault.com/a/1190000000494036
2014-05-05T20:50:57+08:00
2014-05-05T20:50:57+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
0
<p>1、打开文件</p>
<pre><code>vim ~/.bashrc
</code></pre>
<p>2、添加别名</p>
<pre><code>alias del=trash
alias dell="ls ~/.trash"
trash(){
mv $@ ~/.trash/
}
</code></pre>
<p>3、删除方法</p>
<pre><code>del xxx
</code></pre>
<p>4、查看回收站</p>
<pre><code>dell
</code></pre>
<blockquote>
<p>注意:修改后需要重新登录bash才会生效。</p>
</blockquote>
检测手机号码的区域和运营商API
https://segmentfault.com/a/1190000000494034
2014-05-05T20:49:54+08:00
2014-05-05T20:49:54+08:00
风逐蓝天
https://segmentfault.com/u/xdstack
5
<p>【推荐】淘宝话费充值:<a rel="nofollow" href="http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13800138000">http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13800138000</a></p>
<p>【推荐】京东话费充值:<a rel="nofollow" href="http://chongzhi.jd.com/json/order/search_searchPhone.action?mobile=13810088888">http://chongzhi.jd.com/json/order/search_searchPhone.action?mobile=138...</a></p>
<p>【推荐】一号店话费充值:<a rel="nofollow" href="http://life.yhd.com/mobile/findMobileInfo.do?jsonpCallback=jsonp1432469203786&mobileNum=13810017175&chargePrice=100&source=1">http://life.yhd.com/mobile/findMobileInfo.do?jsonpCallback=jsonp143246...</a></p>
<p>K780:<a rel="nofollow" href="http://api.k780.com:88/?app=phone.get&phone=13800138000&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json">http://api.k780.com:88/?app=phone.get&phone=13800138000&appkey...</a></p>
<p>手机在线:<a rel="nofollow" href="http://api.showji.com/Locating/www.showji.c.o.m.aspx?m=13800138000&output=json&callback=querycallback&timestamp=1398860095831">http://api.showji.com/Locating/www.showji.c.o.m.aspx?m=13800138000&amp...</a></p>
<p>其他:<a rel="nofollow" href="https://appyun.sinaapp.com/index.php?app=mobile&controller=index&action=api&outfmt=json&mobile=13800138000">https://appyun.sinaapp.com/index.php?app=mobile&controller=index&a...</a></p>