input、select等表单元素与相邻文字对齐
以前都是把多选框放到一个单独的表格单元格。
现在才知道,用css更简单:
input,select,button{
vertical-align:middle;
}
再加个表格隔行变色和鼠标移动变色:
表格隔行变色
生活在继续,希望就不灭,一切的美好也会在痛苦中茁壮成长
以前都是把多选框放到一个单独的表格单元格。
现在才知道,用css更简单:
input,select,button{
vertical-align:middle;
}
再加个表格隔行变色和鼠标移动变色:
表格隔行变色
淡水碰到了,记下来备忘。
作者:Hily 原始链接:http://hily.me/blog/2009/04/system-time-kohana-captcha-fail/
版权声明:可以转载,转载时务必以超链接形式标明文章原始出处和作者信息及版权声明
好糗……
最近玩 Kohana 碰到太多诡异的问题,比如所有模板都要以 UTF8 无 BOM 的编码格式保存,否则 IE 下显示会有问题。自己写的 helper 类也要保存成 UTF8 无 BOM 的编码格式,否则也会出现类似的问题。
这一系列诡异的问题,把我原本清晰的思路也被搞乱了。
测试代码(使用 Kohana 文档上的):
验证代码在 Firefox 下工作正常,在 IE、Chrome 下都不能正常工作,这肯定就是浏览器之间的差别造成的。
跟踪后发现在 IE 下调用:
Session::instance()->get(’captcha_response’))
总是返回空。怎么会取不到 Session 的 Cookie?
用 Fiddler 看了看 Cookie,发现 expires 时间比我当前系统的时间,也就是说 Session 类写了一个过期的时间到 Cookie 中,所以总是取不到 Session 的 Cookie 信息。按我的理解,写入一个过期的 Cookie,本就不应该被取到,而 Firefox 下还能取到这条过期的 Cookie,应该算 FF 的一个 Bug 吧。
怎么会出现过期时间?
因为我的 Kohana 是放在虚拟机里跑的,而我的虚拟机长年都是 suspend 而不是 poweroff,所以时间自然要比当前时间慢 = =
这类诡异的问题在 QQ 群上问是几乎不可能找到答案的,所以关键时刻还是得靠自己解决啊。
– EOF –
以上代码,比较严谨。关键字为空时,可以正常alert。以下代码,看似没有什么问题,但是却不能正常提示。
看来还是要在if里把判断包含全面了才安心啊。
-_-!!!这里长草了,来除草了。最近试用netbeans for php,感觉不错。里面的代码折叠比较好看,也好用。
不过自选代码的折叠,还是要深挖一下才出来的。eclipse 系列的 php IDE,的自选代码折叠怎么搞呢?不晓得。也许徐徐知道,自己问去吧XD
可以做成Code Complete ,更加方便使用。
嗯,netbeans4php越来越好用了。
淡水摸索了一阵子。
说说吧,先说说wsdl文件的建立。
用zend studio for eclipse 或是 easyeclipse for php都可以建立。但是zse方便一些。例如提供一个简单的加法服务:
在zes的php explorer中右击sum.php,
点击export,选择wsdl file,
填写配置名(随便写,只是ide方便复用),file name:选择保存路径和名称,exported files里add提供服务的php文件,勾选出现的目标类,下一步,结束。
再配置一下address location的php soapserver 的url就可以了。
关键是注释一定要到位,否则zse生成的wsdl就不对了,就只能自己设计了。
第二个要说的,php提供的soap中的__gettypes()函数对我来讲就是个鸡肋。不仅zse生成的wsdl无法提供类型说明,而且__getFunctions()已经很明确了参数类型了,要它何用?费解
上午折腾了一下,可以写个详细步骤出来了。
预期目标:
搭建一个apache下的svn服务,服务地址 http://localhost/svn
本地环境:
已经装有xampplite集成环境。
svn的服务目录为D:\svnroot
已经安装好了小乌龟(TortoiseSVN)
安装步骤:
1,下载的适用于windows的Subversion,我下载的是Setup-Subversion-1.5.3.msi
这里注意要和apache的版本对应,我是apache2.2的。
双击安装它,这个没说头。
2,从subversion的安装目录Subversion\bin下复制相应的文件到apache的modules目录中
有三个,libdb44.dll mod_authz_svn.so mod_dav_svn.so
(淡水还把Subversion\bin下所有的dll文件都复制到了apache的bin下)
3,配置apache的httpd.conf文件
这个是个容易出差错的地方
把下两行的注释去掉:
;LoadModule dav_module modules/mod_dav.so
;LoadModule dav_fs_module modules/mod_dav_fs.so
再添加以下两行:
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
ok,下面配置一下svn的路径,用户认证,权限控制:
DAV svn
#D:/svnroot 是指定SVN的目录,该代码适合该目录下 仅有1个资源库的情况
#若有多个资源库,则可以直接用SVNParentPath D:/svnroot
SVNPath D:/svnroot
#限定各个用户或组在版本库中目录的访问权限
AuthzSVNAccessFile D:/xampplite/apache/bin/svn.useraccess
Require valid-user
#认证的类型
AuthType Basic
#认证的名称,显示于登录提示框
AuthName “CommonFuse SVN”
#存储用户登录信息的文件
AuthUserFile D:/xampplite/apache/bin/svn.userpasswd
Require valid-user
ok,保存它。
4,创建用户
这个用到的是 apache\bin\htpasswd 命令
命令行下,进入到apache\bin目录:
htpasswd -cp svn.userpasswd (username)
回车,后要求输入密码和密码确认。这样就创建了一个用户。要继续添加用户可以
htpasswd -mp svn.userpasswd (username)
c是创键,m是尾部添加修改,p是明码(不加p是md5加密)
5,创建授权
用uestudio创建无bom的文件svn.useraccess保存到apache/bin目录下
[groups]
g_admin = admin
g_test = test# 所有人可以读,管理员可以写
[svn:/]
@g_admin = rw
* = r[svn:/机密文件]
@g_admin = rw
* =[svn:/公告文件]
@g_admin = rw
* = r[svn:/测试组]
@g_admin = rw
@g_test = rw
* =
如果是多个库,则权限文件类似以下
[groups]
g_admin = admin
g_test = test# 所有人可以读,管理员可以写
[/]
@g_admin = rw
* = r[khn:/]
@g_admin = rw
* =[ci170:/]
@g_admin = rw
@g_test = rw
* = r
6,在d:\svnroot下,用tortoiseSVN创建版本库。
7,重启apache。搞定了。
注意点:
先不要启用权限控制。用tortoiseSVN登录进入以后,创建文件夹后,再启用权限控制。
如果想要把地址改成http://localhost/kisssvn,两步:apache的httpd.conf 里 改为
简介
PHP的SOAP扩展可以用来提供和使用Web services。换句话说,PHP开发者可以利用这个PHP扩展来写他们自己的Web services,也可以写一些客户端来使用已有的Web services。
PHP5中的这个SOAP扩展目的是为了实现PHP对Web services的支持。与其它实现PHP对Web services的支持的方法不同,SOAP扩展是用C写的,因此它比其它方法(比较出名的Nusoap类)具有速度优势。
SOAP扩展支持以下规范。
* SOAP 1.1
* SOAP 1.2
* WSDL 1.1
SOAP扩展主要用来处理RPC形式的Web services。不过,你也可以使用文本形式的WSDL文件配合WSDL模式的服务端和客户端。
这个扩展使用 GNOME XML库来处理XML。
扩展中的类
这个扩展实现了6个类。
其中有三个高级的类,它们的方法很有用,它们是 SoapClient,SoapServer和SoapFault。
另外三个类除了构造器外没有其它别的方法,这三个是低级的类,它们是SoapHeader,SoapParam和SoapVar。

SoapClient类
这个类用来使用Web services。SoapClient类可以作为给定Web services的客户端。
它有两种操作形式:
* WSDL 模式
* Non-WSDL 模式
在WSDL模式中,构造器可以使用WSDL文件名作为参数,并从WSDL中提取服务所使用的信息。
non-WSDL模式中使用参数来传递要使用的信息。这个类有许多可以用来使用服务的有用的方法。其中SoapClient::__soapCall()是最重要的。这个方法可以用来调用服务中的某个操作。
SoapServer类
这个类可以用来提供Web services。与SoapClient类似,SoapServer也有两种操作模式:WSDL模式和non-WSDL模式。这两种模式的意义跟 SoapClient的两种模式一样。在WSDL模式中,服务实现了WSDL提供的接口;在non-WSDL模式中,参数被用来管理服务的行为。
在SoapServer类的众多方法中,有三个方法比较重要。它们是SoapServer::setClass(),SoapServer::addFunction()和SoapServer::handle()。
SoapServer::setClass()方法设定用来实现Web Service的类。SoapServer::setClass所设定的类中的所有公共方法将成为Web Services的操作(operation)。
SoapServer::addFunction()方法用来添加一个或多个作为Web Services操作(operation)的函数。
SoapServer:: handle()方法指示Web Service脚本开始处理进入的请求。Web Service脚本是用PHP脚本写的一个或多个SoapServer对象的实例。尽管你可以有不止一个的SoapServer对象,但通常的习惯是一个脚本只拥有一个SoapServer实例。在调用SoapServer::handle()方法之前,Web Service脚本会使用设置在SoapServer对象实例上的任何信息来处理进入的请求和输出的相应。
SoapFault类
这个类从Exception类继承而来,可以用来处理错误。SoapFault实例可以抛出或获取Soap错误的相关信息并按程序员的请求处理。
SoapHeader类
这个类可以用来描述SOAP headers。它只是一个只包含构造器方法的数据容器。
SoapParam类
SoapParam也是一个只包含构造器方法的数据容器。这个方法可以用来描述传递给Web services操作的参数。在non-WSDL模式中这是一个很有用的类,可以用来传递所期望格式的参数信息。
SoapVar类
SoapVar也是一个只包含构造器的低级类,与SoapHeader和SoapParam类相似。这个类可以用来给一个Web services操作传递编码参数。这个类对non-WSDL中传递类型信息是非常有用的。
WSDL VS. non-WSDL模式
Web Services有两种实现模式:契约先行(Contract first)模式和代码先行(Code first)模式。
契约先行模式使用了一个用XML定义的服务接口的WSDL文件。WSDL文件定义了服务必须实现或客户端必须使用的接口。SoapServer和SoapClient的WSDL模式就基于这个概念。
在代码先行模式中,首先要先写出实现服务的代码。然后在大多数情况下,代码会产生一个契约,换种说法,一个WSDL。接着客户端在使用服务的时候就可以使用那个WSDL来获得服务的接口。尽管如此,PHP5的扩展并没有从代码输出一个WSDL的规定,考虑到这种情况,可以在non-WSDL模式下使用 SoapServer和SoapClient。
SOAP扩展与Hello World
这一节介绍如何使用WSDL模式和non-WSDL模式来实现服务和客户端。相对而言,使用WSDL模式来实现服务和客户端会比较容易,假定已经有一个定义了接口的WSDL文件。(淡水对WSDL还比较陌生,就只关注non-wsdl模式了。)
如何使用WSDL模式实现一个Web Service。
在这个Hello World例子的服务中有一个被命名为greet的操作。这个操作有一个字符串形式的名字并返回一个字符串形式的greeting。所用到的WSDL如下:
<wsdl:definitions
xmlns:impl='http://wso2.org/wsf/php/helloService'
xmlns:intf='http://wso2.org/wsf/php/helloService'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns:wsdlsoap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://wso2.org/wsf/php/helloService'>
<wsdl:types>
<schema elementFormDefault='qualified'
xmlns:impl='http://wso2.org/wsf/php/helloService'
xmlns:intf='http://wso2.org/wsf/php/helloService'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace='http://wso2.org/wsf/php/helloService' >
<element name='greet'>
<complexType>
<sequence>
<element name='name' type='xsd:string' />
</sequence>
</complexType>
</element>
<element name='greetResponse'>
<complexType>
<sequence>
<element name='greetReturn' type='xsd:string' />
</sequence>
</complexType>
</element>
</schema>
</wsdl:types>
<wsdl:message name='greetRequest'>
<wsdl:part name='parameters' element='impl:greet' />
</wsdl:message>
<wsdl:message name='greetResponse'>
<wsdl:part name='parameters' element='impl:greetResponse' />
</wsdl:message>
<wsdl:portType name='helloService'>
<wsdl:operation name='greet'>
<wsdl:input name='greetRequest' message='impl:greetRequest' />
<wsdl:output name='greetResponse' message='impl:greetResponse' />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name='helloServiceSoapBinding' type='impl:helloService'>
<wsdlsoap:binding transport='http://schemas.xmlsoap.org/soap/http' style='document' />
<wsdl:operation name='greet'>
<wsdlsoap:operation soapAction='helloService#greet' />
<wsdl:input name='greetRequest'>
<wsdlsoap:body use='literal' />
</wsdl:input>
<wsdl:output name='greetResponse'>
<wsdlsoap:body use='literal' />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name='helloService'>
<wsdl:port binding='impl:helloServiceSoapBinding' name='helloService'>
<wsdlsoap:address location='http://localhost/hello/hello_service_wsdl.php' />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>WSDL模式服务
下面是WSDL模式的服务所使用的SOAP扩展API代码:
function greet($param) {
$retval = 'Hello '.$param->name;
$result = array(’greetReturn’ => $retval);
return $result;
}$server = new SoapServer(’hello.wsdl’);
$server->addFunction(’greet’);
$server->handle();
?>在这个服务的实现过程中,函数实现了WSDL所定义的服务操作greet,greet操作有一个WSDL指定的参数,按照greet操作的语义,这个参数是一个用户的名字。最后handle调用了触发处理请求的服务对象。
WSDL模式客户端
客户端代码如下
try {
$client = new SoapClient('hello.wsdl');
$result = $client->__soapCall(’greet’, array(array(’name’ => ‘Sam’)));
printf(”Result = %s”, $result->greetReturn);
} catch (Exception $e) {
printf(”Message = %s”,$e->__toString());
}
?>客户端代码中,首先创建一个使用WSDL文件作参数的SoapClient实例。接着__soapCall()调用作为参数传入它的操作,也就是greet和传入操作的参数。
请求和响应当你将上述的PHP脚本放在你web服务器目录下的文档中,并利用WEB浏览器或在PHP解析器的命令行调用脚本,客户端发送一个SOAP请求到服务端脚本,服务端将向客户端发送一个SOAP响应来响应客户端的请求。
下面是客户端所发送的SOAP请求:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://wso2.org/wsf/php/helloService">
<SOAP-ENV:Body>
<ns1:greet>
<ns1:name>Sam</ns1:name>
</ns1:greet>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>下面是服务端响应上诉请求而发送的SOAP响应:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://wso2.org/wsf/php/helloService">
<SOAP-ENV:Body>
<ns1:greetResponse>
<ns1:greetReturn>Hello Sam</ns1:greetReturn>
</ns1:greetResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>上面的SOAP消息都是利用WSDL模式的服务端和客户端来获取的。也可以利用non-WSDL模式的服务端和客户端来产生与上面相同的SOAP消息。但是,PHP代码必须有一点改变。下一节会说明如何使用non-WSDL模式。
non-WSDL模式服务端
在non -WSDL模式中,想WSDL模式一样首先实现greet函数的功能,但是函数实现的方式跟WSDL模式稍稍有所不同。在non-WSDL模式中,我们必须返回一个SoapParam对象作为响应,而不是一个数组。创建服务时,第一个参数设为null,说明没有提供WSDL;接着传递一个选项作为参数,这个选项参数是服务的URI。最后像WSDL模式一样调用剩下的方法。
non-WSDL模式客户端
在non-WSDL模式中,因为没有使用WSDL,传递了一个包含服务所在位置和服务URI的参数数组作为参数。然后象WSDL模式中一样调用__soapCall()方法,但是使用了SoapParam类用指定格式打包参数。返回的结果将获取greet中的响应。
嗯,又找到一些好玩的东西,web service。
有个叫Nusoap类,在php4下比较流行。但是淡水这次玩的是php5,所以他就没戏了。
先恶补一下相关知识。
先要打开php5的web service扩展。linux下,嗯,好像不会-_-!。windows下,把php.ini文件中 extension=php_soap.dll 去掉注释即可。
方法:
SoapClient->__soapCall()
说明:
class SoapClient {
mixed __soapCall ( string function_name, array arguments [, array options [, mixed input_headers [, array &output_headers]]])
}
In WSDL mode, you can simply call SOAP functions as SoapClient methods. This method useful in non-WSDL mode when soapaction is unknown, uri differs from the default or when sending and/or receiving SOAP Headers
返回值:
一个简单类型的返回值,或是一个关联数组
例子:
1.in WSDL mode
soapCall应用web service,例子用的是asp.net的web service,提供service.asmx页面,调用及查看都比较简单,手册上的example也大多是这个类型,比较简单.
SOAP发送的协议:
POST /servicepath/service.asmx HTTP/1.1
Host: 211.186.1.4
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: “http://211.186.5.15/Service/ServiceMethod”
调用方法:
2.in non-WSDL mode
这种情况下soapaction is unknown
SOAP发送协议:
POST /services/SoapMethod?WSDL HTTP/1.1
Host: 220.211.1.12:8088
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.2.5
Content-Type: text/xml; charset=utf-8
SOAPAction: “urn:SoapMethod#ServiceMethod”
Content-Length: 1297
调用方法:
附注一下:
class SoapParam {
__construct ( mixed data, string name )
}
参数:
data
The data to pass or return. You can pass this parameter directly as PHP value, but in this case it will be named as paramN and the SOAP Service may not understand it.
name
参数名
以前是用codeigniter做的,但是为了更敏捷的开发,提高生产效率(其实是要偷懒),所以开始摸索kohana,并为之着迷(主要是ORM)。
为了尽快上手kohana,所以把以前公布的企业站又用kohana改写一番。
现在前端已经完成。
kohana版,为了简化代码,使用了ORM
Codeigniter版,采用了他提供的AR
可以自己感觉一下执行效率如内存占用
kohana版http://www.tsingfeng.com/khn
一般结果:Page rendered in 0.0301 seconds.UseMem 1.62MB.
Codeigniter版http://www.tsingfeng.com/ci
一般结果:Page rendered in 0.0248 seconds.UseMem 1.78MB.
淡水没有专业的测试经验,只是凭框架本身提供的简陋数据和直觉判断。差不多了,如