归档时间:十月, 2013

PHP 开发环境搭建——Nginx+PHP+Eclipse(PHP)

十 10 2013 由 创建在标签 开发

概述

以前做PHP时搭建服务器时整理的文档,现将它与大家分享。本文描述PHP环境的搭建步骤,以及配置过程;形成一个能够通过IDE进行单步调试的开发测试环境,节省开发时间。

软件准备

Windows7 64位系统

软件包

php-5.5.1-nts-Win32-VC11-x64

eclipse-php-helios-SR2-win32-x86_64

nginx-1.4.2

php_xdebug-2.2.3-5.5-vc11-nts-x86_64.dll

环境搭建

软件包均使用的是绿色版,可以打包直接拷贝(由于当前配置的机器是64位,32位需要重新配置)。

HTTP server

当前安装使用Nginx,也可以使用其他的Server,可以在此补充。

Nginx

配置使其支持PHP请求,找到如下所示首行的文本,去掉这块的注释(删除#号);把标记为红色的/scripts改为”$document_root”,这里的”$document_root”就是指前面”root”所指的站点路径。

location ~ \.php$ {
root D:/web/website;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

Nginx使用PHP需要使用CGI,所以PHP和Nginx都需要配置CGI参数。

PHP

PHP主要配置三个方面,一个是扩展包,另一个是关于CGI参数的解析,还有一个是关于与eclipse联合单步调试的配置。

扩展包

; extension_dir = "ext" 改为
extension_dir = "ext"

CGI参数修正

;cgi.fix_pathinfo=1 改为
cgi.fix_pathinfo=1

XDebug扩展

将下载的XDebug扩展的dll放到php的ext文件夹中,编辑php.ini,在最后添加如下的配置:

[Xdebug]
zend_extension = php_xdebug-2.2.3-5.5-vc11-nts-x86_64.dll
;下面的线程安全版本的配置
;zend_extension_ts = php_xdebug-2.2.3-5.5-vc11-nts-x86_64.dll
xdebug.remote_enable=true
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9001
xdebug.remote_mode = req
xdebug.remote_handler=dbgp

XDebug配置成功后调用phpinfo会显示有Xdebug运行,如果没有如图 31所示的Xdebug信息则说明配置失败。


图 31:XDebug配置后phpinfo显示

Eclipse

运行

Eclipse运行时使用的是jre运行,jre已经放在eclipse配置文件中。

eclipse.ini中添加如下配置(jre放在eclipse根目录下,下载的jre有版本号,此配置中已经把版本号删除):

-vm
jre/bin/javaw.exe

注:如果电脑上已经安装jdk,可以不用下载安装jre,也可以不用修改配置文件。

配置单步调试

在Window -> Preferences窗口的左边选择PHP -> Debug(如图 32),在窗口右边的PHP Debugger这一项中选择XDebug,这个选项的右边有个Configure链接,点进去可以对XDebug进行设置,请确保XDebug使用的端口号与php.ini文件中指定的相同(通常为9001)。


图 32:调试选项

调试的使用

打开 Eclipse ,新建立一个PHP Project,我继续建立一个测试项目,打开 index.php 页面。选择 Eclipse 菜单里的 Run –>Run Configurations,设置一下:


图 33:运行配置选项卡


图 34:开始调试

其他

自动运行和停止脚本

在启动脚本中,由于windows不能像Linux那样用&符号将程序在后头运行,所以在需要使用RunHiddenConsole工具,这样就能让windows程序在后台运行。启动脚本如下:

echo Starting PHP FastCGI...
RunHiddenConsole D:/web/php-5.5.1-nts/php-cgi.exe -b 127.0.0.1:9000 -c D:/web/php-5.5.1-nts/php.ini
echo Starting nginx...
RunHiddenConsole D:/web/nginx-1.4.2/nginx.exe -p D:/web/nginx-1.4.2

停止脚本:

echo off
echo Stopping nginx...
taskkill /F /IM nginx.exe > nul
echo Stopping PHP FastCGI...
taskkill /F /IM php-cgi.exe > nul
exit

遇到的问题和解决方案

Php不能运行,提示缺少DLL错误

这个是由于系统没有安装VS造成的,在PHP的下载首页可以看到提示到微软的官网上下载VC11的补丁;

不能断点调试

由于php和eclipse的配置造成的。一个是端口的冲突,由于FastCGI使用的是9000端口,按照网上的默认配置XDebug还是使用9000端口,在保证端口能够使用的情况下还要注意端口不要产生冲突;另一个是因为XDebug配置是使用的是extension参数而不是使用zend_extension。

参考资料

说明:本文中的图片也引用于上面两个资料,而不是自己配置时实际执行时截屏,在配置过程中仅有版本号不同,其余均与两个资料中的情况相同。

无评论

udev的使用

十 08 2013 由 创建在标签 开发

UDEV的文章网上有很多,但是很多都是直接转载过来,所以搜了很久都是相同的东西。关于UDEV英文的资料已经很全面了,我也不会去翻译那些文档。我主要从如何使用着手去写这篇文章,让读的人能够很快找到自己想要的东西。

配置

Udev有两种配置,一种是udev的配置,另一种是热插拔设备的规则配置;

udev配置文件

一个典型的配置如下:

# cat /etc/udev/udev.conf
# udev.conf
# The initial syslog(3) priority: "err", "info", "debug" or its
# state can be changed with: "udevcontrol log_priority=".
udev_root="/dev/" # 设备节点的根目录
udev_rules="/etc/udev/rules.d" #规则文件的路径,里面的具体文件格式在下一节介绍
udev_log="err" #udev的日志级别

规则配置文件

规则文件以.rules为后缀名,每一个文件处理一系列规则来帮助udev分配名字给设备文件以保证能被内核识别。

在一个规则文件中,以”#”开头的行被认为是注释。每一个非空的行都是一条规则,规则不能跨越多行。一条规则由多个规则语句(条件判断或赋值)组成,每个规则间用‘,’分隔。如 key OP vaule(OP表示操作符,后面提到的key和value均指此处)。

操作符

操作符如下表所示。

操作符 意义
== 比较是否相等
!= 比较是否不相等
= 给一个key 赋值。 表示一个列表的key会被重置,并且把这个唯一的值传给它
+= 将一个值增加到key中
:= 将一个值传给一个key,并且不允许再修改这个key

匹配关键字

这些关键字用于匹配设备,可以根据指定的条件执行特定的动作。

关键字 意义
ACTION 匹配事件的动作名
DEVPATH 匹配事件的设备devpath
KERNEL 匹配事件的设备名
NAME 匹配网络接口或者设备节点的名字。NAME 只有在前面的规则赋值之后才可以使用。
SYMLINK 匹配设备节点符号链的名字。SYMLINK 只有在前面的规则赋值之后才可以使用。可以有多个symlinks,只需要匹配一个。
SUBSYSTEM 匹配设备子系统,如block表示块设备,net代表网络等;
DRIVER 匹配设备的驱动名。只对绑定到一个驱动的设备有用。
ATTR { filename } 匹配事件设备的 sysfs 属性。
KERNELS 向上搜索devpath,直到找到一个匹配的设备名
SUBSYSTEMS 向上搜索devpath,直到找到一个匹配的子系统名
DRIVERS 向上搜索devpath,直到找到一个匹配的驱动名
ATTRS{ filename } 向上搜索devpath,直到找到一个含匹配 sysfs 属性的设备
ENV{key} 内核设置的环境变量
TAG 设备的 tag(暂时没有明白这个的用途)
TEST{octal mode mask} 测试一个文件是否存在,可以指定一个8进制的模式掩码。
PROGRAM 执行一个程序。如果程序成功返回, key 为 true。设备的属性被放在被执行进程的环境变量中,该程序的输出为 stdout, 可以从 RESULT 这个 key 读取。
RESULT 匹配最近一次 PROGRAM 调用的返回字符串。它应该在 PROGRAM 之后使用。

注:加了s的关键字会找其devpath的父目录,可以使用udevinfo -a -p /sys/***来查看具体的路径;

赋值关键字

这部分关键字用于修改设备的属性或者环境变量。

操作符 意义
NAME 修改网络设备的节点
SYMLINK 创建设备节点的符号链接;
OWNER, GROUP, MODE 设备节点的属性,用于修改用户组的权限
ATTR {key} 修改sysfs中设备属性的值
ENV {key} 修改环境变量
RUN 对于特定设备指定执行的命令
LABEL GOTO 可以跳到的地方
GOTO 跳到下一个带有匹配名字的 LABEL 处

上面对基本的配置进行了简单的介绍,现在看了一下之后基本上就是man手册里面的内容了,可以参考man udev中的内容。

配置实例

  • 网络设备的开机自动up和更名
SUBSYSTEM=="net", ACTION=="add", KERNEL=="eth*", NAME="lan", RUN+="/sbin/ifconfig lan up"
SUBSYSTEM=="net", ACTION=="add", KERNEL=="lo", RUN+="/sbin/ifconfig lo up"

上例中,网络设备的子系统名字是“net”,在开机时会有“add”事件,kernel中用了*号来匹配设备号,后面的NAME用于将eth0改成lan,这里之所以这样是因为我们的嵌入式设备只有一个网卡,不会因为多个网卡而造成冲突,同时将eth*改为lan的目的是为了管理起来方便(这样每次设备插入时就自动改为lan,不需要改上层的软件代码,增强代码的可移植性);最后RUN用于将接口UP。

  • 磁盘热插拔
ACTION=="add", KERNEL=="sd[a-z][1-9]", SUBSYSTEM=="block",  SYMLINK+="disk/by-name/%k"
ACTION=="add", KERNEL=="sd[a-z][1-9]", SUBSYSTEM=="block", RUN+="/bin/mkdir -p /disk/%k"
ACTION=="add", KERNEL=="sd[a-z][1-9]", SUBSYSTEM=="block", RUN+="/bin/mount -t auto /dev/%k /disk/%k"
ACTION=="remove", KERNEL=="sd[a-z][1-9]", SUBSYSTEM=="block", RUN+="/bin/umount -l /disk/%k"
ACTION=="remove", KERNEL=="sd[a-z][1-9]", SUBSYSTEM=="block", RUN+="/bin/rm -rf /disk/%k"

磁盘热插拔分为两个部分,一个是磁盘的插入,另一个是磁盘的移除;插入时现在devfs中创建按磁盘名字区分的链接;第二句穿件要mount的目录;第三句是自动mount到刚刚创建的目录;最后两句是移除磁盘时的操作,即先umount,再删除mount的路径。

udevinfo工具

通过udevinfo工具可以查看到设备的一些变量,这样可以帮助我们来写规则文件。下面是一个磁盘设备在执行udevinfo命令后的输出。

  looking at device '/block/sdb/sdb1':
    KERNEL=="sdb1"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{dev}=="8:17"
    ATTR{partition}=="1"
    ATTR{start}=="63"
    ATTR{size}=="7892929"
    ATTR{ro}=="0"
    ATTR{alignment_offset}=="0"
    ATTR{discard_alignment}=="0"
    ATTR{stat}=="     322      391      800     4900      351    43241    43592   464200        0     7700   469100"
    ATTR{inflight}=="       0        0"

  looking at parent device '/devices/platform/hiusb-ehci.0/usb1/1-1/1-1:1.0/host3/target3:0:0/3:0:0:0/block/sdb':
    KERNELS=="sdb"
    SUBSYSTEMS=="block"
    DRIVERS==""
    ATTRS{dev}=="8:16"
    ATTRS{range}=="16"
    ATTRS{ext_range}=="256"
    ATTRS{removable}=="1"
    ATTRS{ro}=="0"
    ATTRS{size}=="7892992"
    ATTRS{alignment_offset}=="0"
    ATTRS{discard_alignment}=="0"
    ATTRS{capability}=="51"
    ATTRS{stat}=="     323      391      808     4900      351    43241    43592   464200        0     7700   469100"
    ATTRS{inflight}=="       0        0"
    ATTRS{events}=="media_change"
    ATTRS{events_async}==""
    ATTRS{events_poll_msecs}=="-1"

  looking at parent device '/devices/platform/hiusb-ehci.0/usb1/1-1/1-1:1.0/host3/target3:0:0/3:0:0:0/block':
    KERNELS=="block"
    SUBSYSTEMS==""
    DRIVERS==""

  looking at parent device '/devices/platform/hiusb-ehci.0/usb1/1-1/1-1:1.0/host3/target3:0:0/3:0:0:0':
    KERNELS=="3:0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS=="sd"
    ATTRS{device_blocked}=="0"
    ATTRS{type}=="0"
    ATTRS{scsi_level}=="3"
    ATTRS{vendor}=="ADATA   "
    ATTRS{model}=="USB Flash Drive "
    ATTRS{rev}=="0.00"
    ATTRS{state}=="running"
    ATTRS{timeout}=="30"
    ATTRS{iocounterbits}=="32"
    ATTRS{iorequest_cnt}=="0x2b9"
    ATTRS{iodone_cnt}=="0x2b9"
    ATTRS{ioerr_cnt}=="0x1"
    ATTRS{modalias}=="scsi:t-0x00"
    ATTRS{evt_media_change}=="0"
    ATTRS{queue_depth}=="1"
    ATTRS{queue_type}=="none"
    ATTRS{max_sectors}=="240"

  looking at parent device '/devices/platform/hiusb-ehci.0/usb1/1-1/1-1:1.0/host3/target3:0:0':
    KERNELS=="target3:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""
    ATTRS{uevent}=="DEVTYPE=scsi_target"

  looking at parent device '/devices/platform/hiusb-ehci.0/usb1/1-1/1-1:1.0/host3':
    KERNELS=="host3"
    SUBSYSTEMS=="scsi"
    DRIVERS==""
    ATTRS{uevent}=="DEVTYPE=scsi_host"

  looking at parent device '/devices/platform/hiusb-ehci.0/usb1/1-1/1-1:1.0':
    KERNELS=="1-1:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb-storage"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bNumEndpoints}=="02"
    ATTRS{bInterfaceClass}=="08"
    ATTRS{bInterfaceSubClass}=="06"
    ATTRS{bInterfaceProtocol}=="50"
    ATTRS{modalias}=="usb:v125FpC82Ad0100dc00dsc00dp00ic08isc06ip50"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/platform/hiusb-ehci.0/usb1/1-1':
    KERNELS=="1-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{dev}=="189:2"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="80"
    ATTRS{bMaxPower}=="480mA"
    ATTRS{urbnum}=="2092"
    ATTRS{idVendor}=="125f"
    ATTRS{idProduct}=="c82a"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="3"
    ATTRS{devpath}=="1"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="ADATA"
    ATTRS{product}=="ADATA USB Flash Drive"
    ATTRS{serial}=="0000000C082ACB"

  looking at parent device '/devices/platform/hiusb-ehci.0/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{dev}=="189:0"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="  0mA"
    ATTRS{urbnum}=="38"
    ATTRS{idVendor}=="1d6b"
    ATTRS{idProduct}=="0002"
    ATTRS{bcdDevice}=="0300"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="2"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Linux 3.0.8 ehci_hcd"
    ATTRS{product}=="HIUSB EHCI"
    ATTRS{serial}=="hiusb-ehci"
    ATTRS{authorized_default}=="1"

  looking at parent device '/devices/platform/hiusb-ehci.0':
    KERNELS=="hiusb-ehci.0"
    SUBSYSTEMS=="platform"
    DRIVERS=="hiusb-ehci"
    ATTRS{modalias}=="platform:hiusb-ehci"
    ATTRS{companion}==""

  looking at parent device '/devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""
    ATTRS{uevent}==""

参考资料

  1. http://www.linuxsir.org/bbs/thread323186.html
  2. http://www.cnitblog.com/luofuchong/archive/2007/12/18/37831.html
  3. linux man udev;
  4. udev wiki
  5. 编写UDEV规则

 

无评论