删除 MySQL 二进制日志(log-bin)

查找当前有哪些二进制日志文件

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |   1357315 |
| mysql-bin.000002 |       117 |
| mysql-bin.000003 |    404002 |
| mysql-bin.000004 |   2050722 |
| mysql-bin.000005 |    139103 |
| mysql-bin.000006 |     46702 |
| mysql-bin.000007 |       117 |
| mysql-bin.000008 |        98 |
| mysql-bin.000009 |       117 |
| mysql-bin.000010 |      1254 |
| mysql-bin.000011 |       117 |
| mysql-bin.000012 |  29394942 |
| mysql-bin.000013 |    422100 |
| mysql-bin.000014 |       117 |
| mysql-bin.000015 |       117 |
| mysql-bin.000016 |        98 |
| mysql-bin.000017 |       117 |
| mysql-bin.000018 |       117 |
| mysql-bin.000019 |    285300 |
| mysql-bin.000020 |    181229 |
| mysql-bin.000021 |        98 |
+------------------+-----------+
21 rows in set (0.03 sec)

删除bin-log(删除mysql-bin.000018之前的所有二进制日志文件)

mysql> purge binary logs to 'mysql-bin.000018';
Query OK, 0 rows affected (0.08 sec)

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000018 |       117 |
| mysql-bin.000019 |    285300 |
| mysql-bin.000020 |    181229 |
| mysql-bin.000021 |        98 |
+------------------+-----------+
4 rows in set (0.00 sec)

查看日志

mysql> show binlog events;
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000018 |   4 | Format_desc |         1 |          98 | Server ver: 5.0.45-log, Binlog ver: 4 |
| mysql-bin.000018 |  98 | Stop        |         1 |         117 |                                       |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
2 rows in set (0.01 sec)
Posted in Linux, Mysql | Leave a comment

抽象类与接口类

抽象类 abstract

1, 不能被实例化.
2, 抽象方法不能包含方法实现.
3, 包含有抽象方法的类一定要定义为抽象类.
4, 抽象类中可以定义非抽象方法包换构造方法(一个抽象类中可以不包含抽象方法,即抽象类中的方法可以完全都是已实现过的方法).
5, 继承抽象类的子类必须要实现抽象类中所有未实现的抽象方法.
6, 一个类只能继承一个抽象类.

接口 interface

1, 不能被实例化.
2, 接口类中的接口方法只能为接口方法,不能包含方法实现.
3, 实现接口类的子类必须要实现接口类中所有未实现的接口方法.(接口继承接口时不能实现父接口中的接口方法).
4, 一个类可以实现多个接口类.
5, 接口类中可以有成员变量(这些成员变量都是static,final型的,可以将一些公共的属性定义在抽象类中).

接口类是更加抽象的抽象类.

# http://www.enet.com.cn/article/2007/1126/A20071126923475.shtml
# http://ajava.org/course/kfmoshi/15155.html

理解抽象类
在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。

小结

1. abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
2. 在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法; 而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
3. abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。(例如在报警门的例子中, 因为报警门本质上是门, 所以我们定义一个抽象类为门其中包含两个抽象方法:开和关; 门本身没有报警这个功能, 所以我们将报警这个功能放到一个接口类中去;)
4. 实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
5. 接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
6. 抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。
7. 接口中的方法默认都是 public,abstract 类型的。
Posted in Java | Tagged , | Leave a comment

MySQL 4.1+ using old authentication

参考自这里

连接MySQL出现 mysqlnd cannot connect to MySQL 4.1+ using old authentication 错误

打开 /etc/my.cnf 会看到

# Default to using old password format for compatibility with mysql 3.x
old_passwords=1

默认使用 old_passwords 格式, 这是为了兼容 mysql 3.x, 如果没有这个需求, 那就用新的密码方式吧!
具体操作步骤如下:

1、编辑my.cnf注释掉一下行:
   old_passwords = 1

2、重启MySQL
   service mysqld restart
   /etc/inint.d/mysqld restart

3、检查是否有16位的密码
   SELECT user, Length(`Password`) FROM `mysql`.`user`;

4、如果有,把对应的用户名密码用以下SQL更新
   UPDATE mysql.user SET Password = PASSWORD('password') WHERE user = 'username';

5、更新后要刷新
   FLUSH PRIVILEGES;
Posted in Linux, Mysql | Tagged | Leave a comment

在VPS上搭建VPN

参考自

# http://os.51cto.com/art/201011/234004.htm
# http://www.vpsyou.com/centos5-5-install-openvpn/
# http://www.cat-home.org/?action=show&id=11

1, VPS(server) 上操作如下

mkdir -p /root/software/vpn
cd /root/software/vpn

# 下载软件包
wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.05.tar.gz
wget http://swupdate.openvpn.net/community/releases/openvpn-2.2.1.tar.gz

# 解压及安装
tar zxvf lzo-2.05.tar.gz
cd /root/software/vpn/lzo-2.05
./configure
make
make install

tar zxvf openvpn-2.2.1.tar.gz
cd /root/software/vpn/openvpn-2.2.1
./configure
make
make install

# 服务器端设置
cp /root/software/vpn/openvpn-2.2.1/easy-rsa/2.0 -r /etc/openvpn
cd /etc/openvpn

vim vars
# 将 vars 内容修改为
export KEY_COUNTRY="CN"
export KEY_PROVINCE="SH"
export KEY_CITY="shanghai"
export KEY_ORG="studyday.net"
export KEY_EMAIL="kuco@studyday.net"
export KEY_EMAIL=kuco@studyday.net
export KEY_CN=kuco
export KEY_NAME=kuco
export KEY_OU=kuco
export PKCS11_MODULE_PATH=kuco
export PKCS11_PIN=20110804
source ./vars

./clean-all

./build-ca                  # 一路回车

./build-key-server server   # 一路回车,最后要按两次y

./build-key client          # 一路回车,最后要按两次y

./build-dh

cp /root/software/vpn/openvpn-2.2.1/sample-config-files/server.conf /etc/openvpn/

vim /etc/openvpn/server.conf
#将 server.conf 内容修改为
local 184.82.33.161
port 1194
proto udp

dev tun

ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh1024.pem

server 10.8.0.0 255.255.255.0

client-to-client
keepalive 10 120

comp-lzo

persist-key
persist-tun
status /etc/openvpn/keys/openvpn-status.log
verb 4

push "dhcp-option DNS 10.8.0.1"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4" 

ifconfig-pool-persist /etc/openvpn/keys/ipp.txt
# 修改iptables
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j MASQUERADE
/etc/init.d/iptables save
/etc/init.d/iptables restart

# 启动VPN
/usr/local/sbin/openvpn --config /etc/openvpn/server.conf --daemon

2, Windows(client) 上操作如下

# 下载 OpenVPN 并安装

http://swupdate.openvpn.org/community/releases/openvpn-2.2.1-install.exe

# 假设安装路径为
D:\Program Files\OpenVPN

# 将 server 上生成的认证文件下载到 D:\Program Files\OpenVPN\config\ 目录下
/etc/openvpn/keys/ca.crt
/etc/openvpn/keys/client.crt
/etc/openvpn/keys/client.key

# 将 D:\Program Files\OpenVPN\sample-config\client.ovpn 复制到 D:\Program Files\OpenVPN\config\ 

# 修改 D:\Program Files\OpenVPN\config\client.ovpn
# 将 client.ovpn 内容修改为
client

dev tun
proto udp

remote 184.82.33.161 1194

persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
ns-cert-type server
comp-lzo
verb 3

redirect-gateway def1
route-method exe
route-delay 2
Posted in Linux, shell | Tagged , | Leave a comment

Windows 下安装 Memcached

#下载:
#  http://code.jellycan.com/memcached/
#  http://code.jellycan.com/files/memcached-1.2.6-win32-bin.zip

#一个带有 memcached 的管理器(很好用):
#  http://allegiance.chi-town.com/MemCacheDManager.aspx
Posted in NoSQL | Tagged | Leave a comment

理解 Memcache 的服务器端与客户端

什么是 memcache ?
什么是 memcached ?
什么是 memcache.so ?
什么是 memcached.so ?
什么是 libmemcached.so ?
什么是 libmemcache ?
什么是 libmemcached ?

如果刚刚才接触 memcache 的同学看到上面几个问题一定会头皮发麻, 上面几个名词究竟是什么意思, 它们之间的区别与联系是什么呢?

什么是 memcache ?

memcache 是一种基于 C/S 架构的内存式缓存系统.

什么是 memcached ?

memcached (http://memcached.org/) 是 memcache 这种缓存系统的服务器端. 它以后台守护进程运行于服务器上.
memcached 同时也是 memcache 服务器端的后台守护进程名, memcache 服务器端启动命令类似于:
# /usr/local/bin/memcached -d -m 1000 -u root -l 127.0.0.1 -p 11211 -c 256 -P /tmp/memcached.pid

什么是 memcache.so / memcached.so / libmemcached.so ?

做为一种 C/S 架构的系统, 统一的服务器端(memcached)可以有很多种不同的客户端连接它对它进行操作. 问题中的三种 xxx.so 就是 memcache 的针对 PHP 的三种不同的客户端.

最流行的网络语言 PHP 本身并不能直接与 memcache 服务器端连接和通讯, 但它可以通过加载 PHP 扩展的方式使自己具有连接 memcache 服务器端并操作其数据的功能. 我们可以把 PHP 加载的这种扩展理解为 memcache 缓存系统的 PHP 语言下的客户端. 最常见的操作 memcache 的 PHP 扩展有两种.

# 一种是 memcache.so (Window下是dll),
源码下载地址 http://pecl.php.net/package/memcache
PHP手册说明页 http://au.php.net/manual/zh/book.memcache.php

# 另外一种是 memcached.so
源码下载地址 http://pecl.php.net/package/memcached
PHP手册说明页 http://au.php.net/manual/zh/book.memcached.php
与 memcache.so 不同的是 memcached.so 在编译安装时是依赖于 libmemcached 客户端库的, 

# 还有一种不常见的是 libmemcached.so
源码下载地址 https://github.com/kajidai/php-libmemcached

什么是 libmemcache / libmemcached 端呢?

和前面的 xxx.so 一样, 这两个 libxxx 也是另外两种不同的客户, 只不过它俩不是给 PHP 语言用的, 而是给 C/C++ 用的.

# libmemcache
源码下载地址 http://people.freebsd.org/~seanc/libmemcache/

# libmemcached
源码下载地址 http://libmemcached.org/libMemcached.html
libmemcached 是 C/C++ 语言下的操作 memcache 服务器端的客户端库, 因为 PHP 的扩展也是用 C/C++ 写的, 所以编译安装 memcached.so 时依赖 libmemcached 也是可以理解的.

memcache.so / memcached.so 二者的区别: http://code.google.com/p/memcached/wiki/PHPClientComparison
还有更多的 memcache 客户端信息可以在 http://code.google.com/p/memcached/wiki/Clients 这里找到.

其实总的来说 memcache 的概念就只有两类, 一类是服务器端, 一类是客户端. 在讨论 memcache 的时候理解清楚这两类概念就OK了, 这样就不会出现别人说 memcache 客户端的问题你却理解成 memcache 服务器端的问题了. 在讨论客户端时也要讲清楚是什么语言的哪一个客户端, 因为 memcache 客户端中有很多名字都差不多, 如果都笼统的用 "memcache 客户端" 来讨论, 往往会造成别人说的是A, 自己理解却是B了.

Posted in PHP, Tips | Tagged , | Leave a comment

理解PHP中Mysql的永久连接

参考自这里

PHP程序员应该都知道连接MySQL数据库可以使用mysql_pconnect(永久连接)函数,使用数据库永久连接可以提高效率,但是实际应用中数据库永久连接往往会导致出现一些问题,通常的表现就是在大访问量的网站上时常发生断断续续的无法连接数据库的情况,出现类似"Too many connections in ..."的错误提示信息,重新启动服务器又正常了,但过不了一会儿又出现同样的故障。对于这些问题的成因,恐怕就不是每个人都能说清楚的了,虽然PHP文档里有一些相关资料,但是解释的并不浅显易懂,这里我厚着脸皮试图做一个简单的讨论,所述观点不见得全都正确,欢迎大家反馈意见。

首先看看数据库永久连接的定义:
永久的数据库连接是指在脚本结束运行时不关闭的连接。当收到一个永久连接的请求时。PHP 将检查是否已经存在一个(前面已经开启的)相同的永久连接。如果存在,将直接使用这个连接;如果不存在,则建立一个新的连接。所谓“相同”的连接是指用相同的用户名和密码到相同主机的连接。

PHP使用永久连接方式操作MySQL是有前提的:就是PHP必须安装为多线程或多进程Web服务器的插件或模块。最常见的形式是把PHP用作多进程Apache服务器的一个模块。对于一个多进程的服务器,其典型特征是有一个父进程和一组子进程协调运行,其中实际生成Web页面的是子进程。每当客户端向父进程提出请求时,该请求会被传递给还没有被其它的客户端请求占用的子进程。这也就是说当相同的客户端第二次向服务端提出请求时,它将有可能被一个不同的子进程来处理。在开启了一个永久连接后,所有不同子进程请求SQL服务的后继页面都能够重新使用这个已经建立的 SQL服务器连接。它使得每个子进程在其生命周期中只做一次连接操作,而非每次在处理一个页面时都要向 SQL 服务器提出连接请求。每个子进程将对服务器建立各自独立的永久连接。PHP本身并没有数据库连接池的概念,但是Apache有进程池的概念, 一个Apache子进程结束后会被放回进程池, 这也就使得用mysql_pconnect打开的的那个mysql连接资源可以不被释放,而是依附在相应的Apache子进程上保存到了进程池中。于是在下一个连接请求时它就可以被复用。一切看起来似乎都很正常,但是在Apache并发访问量大的时候,如果使用mysql_pconnect,会由于之前的Apache子进程占用的MySQL连接没有close, 很快使MySQL达到最大连接数,使得之后的请求可能得不到响应。

上面的部分文字是摘抄自PHP文档,看起来可能还是有些文绉绉的不好理解,那么我就用大白话再举一个例子来说明问题:

假设Apache配置最大连接数为1000,MySQL配置最大连接数为100,当Apache服务器接到200个并发访问的时候,其中100个涉及到数据库访问,剩下的100个不涉及数据库访问,因为这个时候还不存在可用的数据库连接,所以这里面涉及到数据库访问的100个并发会同时产生100个数据库永久连接,达到了数据库最大连接数,当这些操作没有结束的时候,任何其他的连接都无法再获得数据库连接,当这些操作结束了,相应的连接会被放入进程池,此时Apache的进程池里就有了200个空闲的子进程,其中100个是带有数据库连接的,由于Apache会为访问请求随机的挑选空闲子进程,所以你得到的子进程很可能是不包含数据库连接的那100个中的一个,而数据库连接已经达到了最大值,你也不可能成功的建立新的数据库连接,唉,你便只好不停的刷新页面,哪个时候运气好,碰巧分配到了带有数据库连接的子进程,才能正常浏览页面。如果是大访问量的网站来说,任何时候都可能存在大量的并发,所以浏览者可能就会不停的发现无法连接数据库的现象了。

或许你会说,我们把Apache和MySQL的最大连接数调成一样大不就可以了么?是的,合理的调整这个最大连接数某种程度上会避免这个问题的发生,但是Apache和MySQL的负载能力是不同的,如果按照Apache的负载能力来设置,对于MySQL来说,这个最大连接数就偏大,会产生大量的MySQL数据库永久连接,打个比方,就好像和平时代还要养活一个几百万的军队一样,其开销得不偿失;而如果按照Mysql的负载能力设置,对于Apache来说,这个最大连接数就偏小,有点杀鸡牛刀的感觉,无法发挥Apache的最大效率。

所以按照PHP手册上的介绍,只适合在并发访问不大的网站上使用数据库永久连接,但对于一个并发访问不大的网站来说,使用数据库永久连接带来的效率提高似乎没有太大的意义,从这个角度上来看,我觉得PHP中的数据库永久连接基本上是一个鸡肋的角色,如果你一定要使用数据库连接池的概念,可以尝试一下sqlrelay或者Apache本身提供的mod_dbd,说不定会有惊喜。

Posted in Apache, Mysql, PHP | Tagged , | Leave a comment

Web-Server 中 PHP 的两种工作方式

部分内容参考自这里, 这里

在项目生产环境的 Web-Server 中 PHP.exe 通常以两种工作方式工作, 一种是 Apache 中的模块化方式, 另一种是在 Nginx 中的 FastCGI 方式. 除此之外, PHP.exe 还有一种古老的运行方式: CGI 方式, 这种方式基本上已经被淘汰, 我们可以通过 CGI 方式来很好的理解前两种方式.

CGI 方式是:

#当 Web-Server 启动时:
1, Web-Server 只初始化自身.

#web 请求处理过程是:
1, 用户(浏览器)发起一个 *.php 文件的请求给 Web-Server
2, Web-Server 调用 php.exe
3, php.exe 完成一系列的初始化动作(如: 解析 php.ini , 载入全部扩展, ...)
4, php.exe 初始化完成, 解释 *.php 文件, 返回结果给 Web-Server
5, Web-Server 释放掉 php.exe 占用的资源
6, Web-Server 将结果返回给用户(浏览器)

总的来说, cgi这种处理方式的特点就是每接到一个请求, Web-Server 都要 fork 出一个单独的 cgi 程序的进程来处理, 这种方式的缺点就是如果在高访问需求的情况下, cgi的进程fork就会成为很大的服务器负担, 想象一下数百个并发请求导致服务器 fork 出数百个进程就明白了.

FastCGI 方式是:

#当 Web-Server 启动时:
1, Web-Server 初始化自身
2, Web-Server 载入 FastCGI 进程管理器(通常是PHP-FPM: PHP FastCGI Process Manager)
3, FastCGI 进程管理器自身初始化,
4, FastCGI 进程管理器启动(初始化)多个 CGI 解释器进程并等待来自 Web-Server 的连接(通过 "ps -ef | grep php" 命令或在任务管理器中可看到多个 php-cgi.exe 进程)

#web 请求处理过程是:
1, 用户(浏览器)发起一个 *.php 文件的请求给 Web-Server
2, Web-Server 通过 FastCGI 进程管理器选择并连接到一个空闲的 CGI 解释器
3, Web-Server 将 CGI 环境变量和标准输入发送到 FastCGI 子进程 php-cgi.exe
4, php-cgi.exe 完成处理后将标准输出和错误信息从同一连接返回 Web-Server
5, php-cgi.exe 接着等待并处理来自 FastCGI 进程管理器(运行在 WebServer中)的下一个连接请求
6, Web-Server 将结果返回给用户(浏览器)

总的来说, fastcgi是基于cgi架构的扩展, 他的核心思想就是在 Web-Server 和具体 cgi 程序之间建立一个智能的可持续的中间层, 统管 cgi 程序的运行, 这样 Web-Server 只需要将请求提交给这个层, 这个层再派生出几个可复用的 cgi 程序实例, 然后再把请求分发给这些实例, 这些实例是可控的, 可持续, 可复用的, 因此一方面避免了进程反复 fork, 另一方面又可以通过中间层的控制和探测机制来监视这些实例的运行情况, 根据不同的状况 fork 或者回收实例, 达到灵活性和稳定性兼得的目的.

FastCGI 方式跟 CGI 方式的区别是:

         在web服务器方面                                在对数据进行处理的进程方面
CGI      fork 一个新的进程进行处理                       读取参数, 处理数据, 然后就结束生命期
FastCGI  用tcp方式跟远程机子上的进程或本地进程建立连接        要开启tcp端口, 进入循环, 等待数据的到来, 处理数据

模块化 方式是:

#当 Web-Server 启动时:
1, Web-Server 初始化时会将 php.exe 做为自身的一个模块加载, 这样实际上是将 Web-Server 与 php.exe 做了一个融合, 使 Web-Server 自身拥有了解释 *.php 的能力.

模块化方式运行 php.exe 能将 php.exe 插入到 Web-Server 自身的进程处理, 因此性能有很大改观.
但是这种方法也不是没有缺点的,
例如对于不同的 web server 要按照不同标准开发, 无法做到 Web-Server 无关性;
例如这将输入验证的工作转交给了Web-Server, 没办法自由处理;
例如一旦出现问题将影响整个web server处理流程;
例如插入 Web-Server 进程导致的无法以多用户标示运行, 无法处理虚拟主机权限等.

Posted in Apache, PHP | Tagged , , | Leave a comment

Zend Studio 使用 Xdebug 断点调试

部分内容参考自 这里

1, 下载 Xdebug

# 下载地址
# http://xdebug.org/download.php

# 寻找和自己所安装的 php 版本对应的 Xdebug 下载
# 对于 Windows 版本的 php 可以查看 phpinfo() 函数的打印信息, 查找"PHP Extension Build", 看你的 PHP 版本是 VC 几的,

2, 安装

# 安装说明页
# http://xdebug.org/docs/install

# 对于 Windows 版本, 下载完成后将下载的 dll 文件重命名为 php_xdebug.dll
# 将其复制到 PHP 的扩展目录中去 (例如: D:\Program Files\EasyPHP-5.3.2i\php\ext\ )

3, 修改 php.ini

# 在 php.ini 尾部增加一段, 改完之后重启 Web-Server
[Xdebug]
zend_extension="D:/Program Files/EasyPHP-5.3.2i/php/ext/php_xdebug.dll"

xdebug.profiler_enable=on
xdebug.trace_output_dir="E:/xdebug"       ;xdebug 的数据文件目录
xdebug.profiler_output_dir="E:/xdebug"    ;xdebug 的数据文件目录
xdebug.max_nesting_level = 10000          ;如果设得太小,函数中有递归调用自身次数太多时会报超过最大嵌套数错

xdebug.remote_enable=true                 ;Xdebug允许远程IDE连接
xdebug.remote_host=127.0.0.1              ;允许连接的zend studio的IP地址
xdebug.remote_port=9000                   ;反向连接zend studio使用的端口
xdebug.remote_handler=dbgp                ;用于zend studio远程调试的应用层通信协议

4, 修改 Zend Studio 设置

Window -> Preferences -> PHP -> Debug
# 将左侧 "Default Settings" 中的 "PHP Debugger" 设置为 "XDebug"

5, 在项目中新建一个 test.php 文件

<?php
for ($i = 0; $i < 10; $i++) {
    if ($i==5) {
        echo 'aa';
    }
}
?>

6, 新建一个 Debug 命令

# 点击工具栏上"小蜘蛛"旁边的小箭头 -> Debug As -> PHP Web Page
# 会跳出 Debug 视图
# 在 "if ($i==5) {" 这一行前面加一个断点, 就可以进行单步调试了
Posted in PHP, Tips, Tool | Tagged , , | Leave a comment

Zend Studio 中 PHP Language Library 的用处

如果你在用 Zend Studio 编写 PHP 项目时发现调用系统函数时调试正常, 但是在编写代码时却提示函数未定义"Call to undefined function 'xxx'", 在左侧语法检测状态区域栏总是显示个小黄色的三角形的感叹号, 实在是看着扎眼.

解决办法:

1, 修改项目 .buildpath 文件

# .buildpath 文件内容类似下面的
<?xml version="1.0" encoding="UTF-8"?>
<buildpath>
	<buildpathentry kind="src" path=""/>
</buildpath>

# 新增一句 kind="con"
<?xml version="1.0" encoding="UTF-8"?>
<buildpath>
	<buildpathentry kind="src" path=""/>
	<buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/>
</buildpath>

2, 重置项目编译状态

Project -> Clean -> Clean all projects

3, 重新编译项目

Project -> Build All

4, 完成! 再看看是不是小黄色的感冒号图标消失啦~

P.S. PHP Language Library 中存放的都是一些系统函数以及扩展库函数的定义原型, 当编码时调用这些函数时 Zend Studio 可以根据这些定义原型进行代码提示及补全.

Posted in PHP, Tips | Tagged , | Leave a comment