如何创建简单的批处理(.bat)文件[译文]

如未特别标明,文章均属原创。转载请注明出处 by : 柳公子 http://huliuqing.github.io

想简单的学习批处理文件书写方法,于是翻译了这篇文章。原文在这

1.创建一个.bat文件

在桌面创建一个文本文件,打开刚刚创建的文件。点解 file > save as,并输入批处理文件的文件名以.bat结尾。我创建的是testbat.bat

2.快速掌握基本关键字

如果你会使用命令行模式,那你更容易使用批处理文件,因为批处理文件和命令行模式使用同一种语言。我们仅仅需要通过批处理文件告诉命令行提示符需要做什么,而不是每次都打开命令行输入那些命令。这会为我们节省大量时间。只不过我们需要在批处理文件中添加一些逻辑处理(如简单的循环,条件语句等)

有如下7个简单的命令我们需要去熟悉,在命令行模式下这些命令是不区分大小写的

TITLE - 设置命令提示窗口的窗口标题。默认为“cmd”

ECHO  - 批文件的输出语句。echo之后的所有词语都会在命令行中显示出来

ECHO OFF - 通常放在文件第一行。告诉命令行不要显示bat文件中的命令

PAUSE - 使用此关键字将会在命令行中输出“press any key to continue”,这样我们就可以有更多的时间去查看命令信息。这条语句在调试的时候会非常有用,因为它会终止批文件继续执行除非我们按下任意键。

CLS   - 清屏处理

IPCONFIG 打印输出当前的TCP/IP配置的设置值

ping     ping + ip地址,让我们知道电脑是否正常通讯

3.快速掌握逻辑语句

问题 ① 通过ipconfig/all检测电脑网络设置 ② 预留时间给用户阅读信息 ③ ping google.com以检测我们的电脑是否联网了 ④ 预留时间给用户阅读信息

4.编写.bat文件

echo off    
chcp 65001
echo 通过bat文件,执行查看网络连接是否正常
ipconfig /all
pause
ping www.google.com
echo 所有执行通过
pause

5.点击.bat文件运行

memcache缓存处理简介

如未特别标明,文章均属原创。转载请注明出处。by : 柳公子 http://huliuqing.github.io

进行PHP开发工作3年,直到最近才更专注的去思考关于PHP项目性能问题(一直以来有去了解,但并未深入的去学习)。这篇文章简单讲解在windows平台下PHP开发中,安装和使用memcached缓存系统。

先来看看维基百科关于memcached的解释:

memcached是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用。这是一套开放源代码软件,以BSD license授权发布。 ... memcached的API使用三十二比特的循环冗余校验(CRC-32)计算键值后,将数据分散在不同的机器上。当表格满了以后,接下来新增的数据会以LRU机制替换掉。由于memcached通常只是当作高速缓存系统使用,所以使用memcached的应用程序在写回较慢的系统时(像是后端的数据库)需要额外的代码更新memcached内的数据。

感觉很高端的样子,简单来说memcached是一套分布式的内存对象缓存系统,Key/Value值对以Hashmap方式缓存到内存中,以降低Web应用对数据库、文件读取的压力。

memcached缓存系统组成

一) memcached服务守护程序

服务器守护程序是用C编写的,为客户端程序提供服务。点这里下载

二) memcache客户端程序

客户端程序可以是任意语言编写的,通过memcached协议与守护程序通信。我们这下载PHP开发相关的版本。到这里去下载

memcached服务守护程序安装

  1. 1.下载memcached服务器程序,获取memcached.exe文件。点这里下载

  2. 2.进入命令行模式,使用命令安装memcached c:/memcached/memcached.exe -d install

  3. 3.启动服务 c:/memcached/memcached.exe -d start

默认情况下memcached服务器程序监听11211端口,并指定缓存使用的最大内存为64MB

常用memcached选项参数

-m 指定缓存所使用的最大内存容量,单位是Megabytes,默认是64MB
-u 只有以root身份运行时才指定该参数
-d 以daemon的形式运行
-l 指定监听的地址
-p 指定监听的TCP端口号,默认是11211

//"-d"参数更多选项值
-d install 安装memcached
-d uninstall 卸载memcached
-d start 启动memcached服务
-d restart 重启memcached服务
-d stop 停止memcached服务
-d shutdown 停止memcached服务

更多memcached选项参数,点这里去了解

memcache客户端安装

如果使用XAMPP/WAMP集成开发环境,我们仅需下载php_memcache扩展程序。

  1. 1.下载dll扩展程序(到这里去下载),放于c:/xampp/php/ext/目录下。

  2. 2.开启扩展服务。 进入php.ini文件添加如下extension=php_memcache.dll

  3. 3.重新启动XAMPP/WAMP

使用memcache缓存

超简单示例:

<?php
$memcache = new Memcache;

$memcache->connect('127.0.0.1',11211);
$memcache->add('name','柳公子');
$name = $memcache->get('name');

echo $name;

进入官网手册,了解更多关于memcache相关信息

工具

memcache监控程序

参考资料:

memcache手册中文

How to install Memcached on Windows machine

Memcached基础及示例程序

Memcached配置参数初解

维基百科:memcached

百度百科:memcached

手册:memcached

如何优化PHP网站[译]

转载请注明出处

这是一篇翻译自stackOverflow的文章,由于水平有限难免出错,如果您在阅读的时候发现了,请帮我更正。

如何优化PHP网站

问题如下(原文:PHP website Optimization): 我拥有一个高访问量的网站,需要保证每个访问我站点的用户,都能够在最短的时间内显示出他们请求的页面。 我通过Google搜索大量关于网站访问速度和优化方法的文章,并得出如下几个方案:

    1. 对页面缓存
        通过对页面缓存,我可以让访问更加快速。但是如果我变更了页面的内容,我则必须把页面的内容从缓存中删除并重新对文件进行缓存。
    2. 页面静态化(把页面保存在磁盘中)
        通过页面静态化,我可以比较简单的对它进行维护。只是这样的话我必须每次访问它所在的目录来进行维护工作。

那么究竟如何才能够达到我想要的目的呢?

------------------------------------------------------------------------------------------

来自Book Of Zeus的回答:

Book Of Zeus

对于网站的性能来说,当我们需要获取静态或动态的内容时,减少访问数据库或文件系统的请求数,启用缓存(缓存页面或部分内容)是很重要的一个环节。

在运行动态内容的时候,我们可以使用加速PHP处理的软件:

(一)在这我推荐使用Alternative PHP Cache(通过手册了解更多关于APC信息)。

推荐几篇关于APC的好文章给你:

  1. 1.What is the best PHP accelerator to use?

  2. 2.PHP Accelerators : APC vs Zend vs XCache with Zend Framework

  3. 3.Lighttpd – PHP Acceleration Benchmarks

(二)如果是缓存内容或整个页面的话,最好使用MemcachedRedis进行缓存。

  1. 1.memcached 一个高性能的分布式内存对象缓存开源系统。用于降低数据库负载,提升动态web程序的访问速度。memcached是通过把从数据库中返回的结果集、调用API返回的结果集或者呈现的页面。在内存中以键值对的形式进行缓存。

  2. 2.Redis 一款高性能键值对存储数据库开源项目。当值为字符,哈希表,列表,集合或排序集合时,它被视作一种数据结构服务程序。

这两个(Memcached和Redis)项目都是用于缓存内容和变量的绝好工具。

推荐几篇有关Memcached和Redis的相关文章:

  1. 1.Redis vs Memcached

  2. 2.On Redis, Memcached, Speed, Benchmarks and The Toilet

  3. 3.Redis vs Memcached

  4. 4.Redis VS Memcached (slightly better bench)

(三)使用varnish,nginx或G-Wan

  1. 1.Varnish 一款专为有大量动态内容web网站设计的HTTP加速器。与其它HTTP加速器相比,如squid在客户端缓存;Apache则仅仅是服务器软件。Varnish则一开始就被设计成为HTTP加速器。

  2. 2.Nginx 是一款由俄罗斯程序员Igor Sysoev所开发轻量级的网页服务器、反向代理服务器以及电子邮件(IMAP/POP3)代理服务器。起初是供俄国大型的门户网站及搜索引擎Rambler(俄语:Рамблер)使用。此软件BSD-like协议下发行,可以在UNIX、GNU/Linux、BSD、Mac OS X、Solaris,以及Microsoft Windows等操作系统中运行

  3. 3.g-wan C编写的Web服务器,比其它采用键值对存储的解决方案更加快速

一些文章:

  1. 1.Serving static files: a comparison between Apache, Nginx, Varnish and G-WAN

  2. 2.Web Server Performance Benchmarks

  3. 3.Nginx+Varnish compared to Nginx

  4. 4.Apache, Varnish, nginx and lighttpd

  5. 5.G-WAN vs Nginx

(to be continued)

Apache Bench 工具介绍

如未特别标明,文章均属原创。转载请注明出处 by : 柳公子 http://huliuqing.github.io

apache benchmark(以下简称ab)是一款基准测试工具,用于描绘当前安装的apache服务器的执行性能,是apache安装的一部分。用户可以模拟对特定URL的任意数量请求来对Web服务器进行负载测试,观察你的apache服务器每秒可以处理多少请求。

ab工具提供以下信息:

  • 传输的总大小
  • Web服务器在模拟流量下每秒可以支持的请求总数
  • 完成一个请求所花费的最长时间
  • 完成一个请求所花费的最少时间

ab语法

ab
    [-A auth-username:password]
    [-c concurrency]
    [-C cookie-name=value]
    [-d]
    [-e csv-file]
    [-g gnuplot-file]
    [-h]
    [-H custom-header]
    [-i]
    [-k]
    [-n requests]
    [-p POST-file]
    [-P proxy-auth-username:password]
    [-q]
    [-s]
    [-S]
    [-t timelimit]
    [-T content-type]
    [-v verbosity]
    [-V]
    [-w]
    [-x <table>-attributes]
    [-X proxy[:port]]
    [-y <tr>-attributes]
    [-z <td>-attributes]
[http://]hostname[:port]/path

ab选项标记

-A auth-username:password 
向服务器提供基本认证信息。用户名和密码之间由一个":"隔开,并将被以base64编码形式发送。无论
服务器是否需要(即是否发送了401认证需求代码),此字符串都会被发送。 

-c concurrency 
一次产生的请求个数。默认设置为1。 

-C cookie-name=value 
对请求附加一个"Cookie:"头行。其典型形式是 name=value 的一个参数对。此参数可以重复。

-d 
不显示"percentage served within XX [ms] table"消息(为以前的版本提供支持)。 

-e csv-file 
产生一个逗号分隔(CSV)文件,该文件包含基准测试的运行结果(其中包含了处理每个相应
百分比[Percentage served]请求(从1%到100%)所需要的相应百分比时间[Time in ms](以微
秒为单位))。由于这种格式已经"二进制化",所以比"gnuplot"格式更有用。 

-g gnuplot-file 
把所有测试结果写入一个"gnuplot"或者TSV(以Tab分隔)文件。此文件可以方便地导入到 Gnuplot,
IDL, Mathematica, Excel中。其中的第一行为标题。 

-h 
显示要用于ab的选项列表。 

-H custom-header 
对请求附加额外的头信息。此参数的典型形式是一个有效的头信息行,其中包含了以冒号分隔的字段
和值(如:"Accept-Encoding: zip/zop;8bit")。 

-i 
执行HEAD请求,而不是默认的GET请求 。 

-k 
启用KeepAlive功能,即在一个HTTP会话中执行多个请求。默认不启用KeepAlive功能。 

-n requests 
在测试会话中所执行的请求个数。默认仅执行一个请求,此时其结果不具有意义,n值最大为50000。

-p POST-file 
包含了POST数据的文件。 

-P proxy-auth-username:password 
对一个中转代理提供基本认证信息。用户名和密码由一个":"隔开,并将被以base64编码形式发送。
无论服务器是否需要(即是否发送了407代理认证需求代码),此字符串都会被发送。 

-q 
如果处理的请求数大于150,ab每处理大约10%或者100个请求时,会在stderr输出一个进度计数。此 
-q 标记可以屏蔽这些信息。

-s 
用于编译中(ab -h 会告诉你)使用了SSL的受保护的https ,而不是http协议的时候。此功能是实验性的,最好不要用。 

-S 
不显示中值和标准偏差值,而且在均值和中值为标准偏差值的1到2倍时,也不显示警告或出错信息。
默认时,会显示最小值/均值/最大值等数值。(为以前的版本提供支持) 

-t timelimit 
测试所进行的最大秒数。内部隐含值是"-n 50000"。它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。

-T content-type 
POST数据时所使用的"Content-type"头信息。 

-v verbosity 
设置显示信息的详细程度,4或更大值会显示头信息,3或更大值可以显示响应代码(404,200等),2或更大值可以显示警告和其他信息。 

-V 
显示版本号并退出。 

-w 
以HTML表格形式输出结果。默认时,它是白色背景的两列宽度的一张表。 

-x <table>-attributes 
设置<table>属性的字符串。此属性被填入<table 这里 > 。 

-X proxy[:port] 
对请求使用代理服务器。 

-y <tr>-attributes 
设置<tr>属性的字符串。 

-z <td>-attributes 
设置<td>属性的字符串。 

运行ab工具

现在我们要运行ab工具来对http://www.github.com来进行基准测试。 运行如下命令:

ab -n 1 http://www.github.com/

输出结果如下

Server Software:
Server Hostname:        www.github.com
Server Port:            80
#服务器信息


Document Path:          /
Document Length:        0 bytes
#文档信息


Concurrency Level:      1
Time taken for tests:   1.651 seconds
Complete requests:      1
Failed requests:        0
Write errors:           0
Non-2xx responses:      1
Total transferred:      107 bytes
HTML transferred:       0 bytes
Requests per second:    0.61 [#/sec] (mean)
Time per request:       1650.709 [ms] (mean)
Time per request:       1650.709 [ms] (mean, across all concurrent requests)
Transfer rate:          0.06 [Kbytes/sec] received
#连接信息


Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      862  862   0.0    862     862
Processing:   788  788   0.0    788     788
Waiting:      788  788   0.0    788     788
Total:       1650 1650   0.0   1650    1650
#连接指标分类

1. 服务器信息部分

一般我们的Web服务器软件会是apache,那么在Server Software : 中会显示 apache : 。 但是由于Web管理员使用安全措施,该字段可能返回其它内容或什么也不返回(如示例)

Server Hostname : 测试主机名
Server Post : 测试主机的Web服务器监听端口号

2. 脚本信息部分

包含基准测试主机的Web文档的信息内容

Document Path :  包含测试请求的文档
Document Length : 包含所有HTML 、CSS、JS、图像及其响应的其它数据的字节数总和

3. 链接信息部分

连接数据包含基准测试信息最核心的反馈信息。 其中最需要关心的内容部分:

    HTML transferred    整个模拟测试中传输的内容正文总大小
    Requests per second 每秒支持的请求数
    Time per request    满足一个请求需要花费的总时间

优化目标:减少HTML transferred 大小,提高Requests per second并降低Time per request值

4. 连接指标分类

在这一部分我们主要关注Total项目中的min : ,max : 列

min : 请求所花费的最短时间
man : 请求所花费的最长时间

参考资料

apache 中文手册

未完待续

详解PHP中对象属性遍历

对象迭代

如未特别标明,文章均属原创。转载请注明出处

by : 柳公子 http://huliuqing.github.io

php官网手册对于遍历对象解释如下:

PHP 5 提供了一种定义对象的方法使其可以通过单元列表来遍历,例如用 foreach 语句。默认情况下,所有可见属性都将被用于遍历。

不过使用简单的foreach遍历对象,仅仅能够遍历出对象实例中可见(public)属性的值。

foreach是如何实现对对象进行遍历的呢?

我们的鸟哥在关于一笔试题(Iterator模式) 一文中分享过foreach源码实现。这边我就拿来主义了:

switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) {
    default:
        case ZEND_ITER_INVALID:
               .....
               break
        case ZEND_ITER_PLAIN_OBJECT: {
                ......
            break;
     case ZEND_ITER_PLAIN_ARRAY:
            .....
            break;

        case ZEND_ITER_OBJECT:
            ......
            break;
}

具体如何使用foreach遍历对象,查看示例:

<?php

class Student{
    private $_identityCard = '360401190001011018';
    public  $_name = '三丰';
    public  $_age  = 800;

    protected $_bloodType = 'O';

    public function __construct(){}
}

$s = new Student();

foreach($s as $key => $v){
    echo 'key ',$key ,' val ',$v ,'</br>';
}

//输出
key :_name val 三丰
key :_age val 800

从输出的结果来看,实例化对象的所有可见(public)属性都给遍历输出出来了。

但是,当我们需要遍历那些非可见对象属性,明显简单的使用foreach遍历对象就不够用了。

好在PHP中有提供内置遍历接口IteratorIteratorAggregate完成对象的遍历工作。 关于Iterator与IteratorAggregate接口如下:

Iterator extends Traversable {
    /* 方法 */
    abstract public mixed current ( void )//返回当前元素。 
    abstract public scalar key ( void )   //返回当前元素的键
    abstract public void next ( void )    //移动当前位置到下一个元素
    abstract public void rewind ( void )  //返回到迭代器的第一个元素
    abstract public boolean valid ( void )//此方法在 Iterator::rewind() 和 Iterator::next()
                                          //方法之后被调用以此用来检查当前位置是否有效
}

IteratorAggregate extends Traversable {
    /* 方法 */
    abstract public Traversable getIterator ( void )//返回一个外部迭代器
}

我们可以通过实现这两个迭代器接口,定义自己的对象遍历规则

1、通过实现IteratorAggregate接口,完成对象属性遍历

我们只需要实现IteratorAggregate中getIterator()方法完成遍历。

class Kungfu implements IteratorAggregate{
    public $_name='飞鸿';
    public $_age = 121;

    protected $_bloodType = 'O';
    private $_isMarried = true;

    public function __construct(){}

    public function getIterator(){
        $members = get_class_vars(__CLASS__);

        return new ArrayIterator($members);
    }
}


$k = new Kungfu();

foreach($k as $key => $v){
    echo 'key ',$key ,' val ',$v ,'</br>';
}
/*
    key _name val 飞鸿
    key _age val 121
    key _bloodType val O
    key _isMarried val 1
*/

2、通过实现Iterator接口,完成对象属性遍历

相对于IteratorAggregate而言,Iterator接口实现起来稍微麻烦一些,需要在实现类中实现所有5个抽象方法。

不过如果我们需要对迭代的对象,进行具体控制的话,使用Iterator的话则更合适。

class Language implements Iterator{
    private $_lang;
    private $_counter=0;

    public function __construct(){      
        $this->_lang = explode(',', 'PHP,C++,C,GO,JAVA,JAVASCRIPT,RUBY,Node.js');
    }

    public function rewind(){
        $this->_counter = 0;
    }

    public function current(){
        //当编程语言的值为JAVA时,返回空
        if($this->_lang[$this->_counter] == 'JAVA'){
            return null;
        }
        return $this->_lang[$this->_counter];
    }

    public function valid(){
        return isset( $this->_lang[$this->_counter]);
    }

    public function next(){
        ++$this->_counter;
    }
    public function key(){
        return $this->_counter;
    }
}

$m = new Language();

foreach($m as $key => $v){
    echo 'key ',$key ,' val ',$v ,'</br>';
}

//结果输出
key 0 val PHP
key 1 val C++
key 2 val C
key 3 val GO
key 4 val 
key 5 val JAVASCRIPT
key 6 val RUBY
key 7 val Node.js

接口Iterator中抽象方法的执行顺序如下图所示: