您的位置:首页 > 编程语言 > PHP开发

php soap实例(一)无wsdl模式

2008-11-03 17:14 429 查看
今晚写个soap实例,选择无wsdl模式。wsdl模式明晚在写。
先写个user类,用pdo链接mysql。
user.php

/**
*this is a user class
*@author:guqin
*
*/
class User{
private $db = NULL;
private $name = 'root';
private $pwd = '123456';
private $dns;
public function __construct(){
$this->dsn = "mysql:host=localhost;dbname=zf";
try{
$this->db = new PDO($this->dsn,$this->name,$this->pwd);
}catch(PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}
}
public function getUser(){
$sql = "SELECT name FROM user";
foreach($this->db->query($sql) as $row){
$result[] = $row;
}
return $result;
}
public function addUser($name,$pwd){
$sql = "INSERT INTO user (name,password) values ('$name','$pwd')";
$count = $this->db->exec($sql);
if($count>0){
return true;
}else{
return false;
}
}
public function getUserById($id){
$sql = "SELECT name FROM user WHERE id >?";
$handle = $this->db->prepare($sql);
$handle->execute(array("$id"));
$result = $handle->fetchAll();
return $result;
}
}

server.php

/**
*this is a soap server test
*@author:guqin
*
*/
require_once('./user.php');
$server = new SoapServer(null,array('uri'=>'http://test-uri/'));
$server->setClass('User');
$server->handle();

client.php

/**
*this is a soap client test
*@author:guqin
*
*/
$client = new SoapClient(null,array('location'=>'http://mysql.guqin.com/server.php','uri'=>'http://test-uri/');
$result = $client->getUser();
print_r($result);
$r = $client->getUserById(46);
print_r($r);

if($client->addUser('k6','88')){
echo "ok";
}
?>

通过http://mysql.guqin.com/client.php就可以看到结果。明晚接着写wsdl模式的。

php webservices之soap篇

May 14, 2008 webservices No Comments
即将做个网站,平台架构是lamp的,用到drupal框架开发,数据一部分要webservices取得和本地mysql存取,用到memcached和google api。所以最近在学习webservices。现在网站和网站之间的交互越来越频繁,用webservices可以解决数据共享,跨平台,跨语言,网站服务和分布式网站等问题。
webservices当前有三种解决方案:soap,rest,xmlrpc。
我决定在项目中用soap来做webservices这块,今天就讲讲对soap的理解,剩下两种以后在讲。先介绍点资料。供大家学习。
soap简介
soap在php中开发有三种,php5 soap,pear soap,nusoap,第一中用c写的,速度较快。后两种用php写的。所以决定用php的soap。在window下开发要打开C:/WINDOWS/php.ini修改下。
extension=php_openssl.dll
extension=php_soap.dll
重启apache,看下是否soap支持。
linux下安装,在编译php时候带上enable-soap。
以下介绍soap使用。
PHP的SOAP扩展可以用来提供和使用Web services。换句话说,PHP开发者可以利用这个PHP扩展来写他们自己的Web services,也可以写一些客户端来使用给定的Web services。
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模式实现一个Web Service。
在这个Hello World例子的服务中有一个被命名为greet的操作。这个操作有一个字符串形式的名字并返回一个字符串形式的greeting。
WSDL模式服务
下面是WSDL模式的服务所使用的SOAP扩展API代码:
PLAIN TEXTPHP:
function greet($param) {
$retval = ‘Hello ‘.$param;
$result = array(’greetReturn’ => $retval);
return $result;
}
$server = new SoapServer(’hello.wsdl’);
$server->addFunction(’greet’);
$server->handle();
?>
在这个服务的实现过程中,函数实现了WSDL所定义的服务操作greet,greet操作有一个WSDL指定的参数,按照greet操作的语义,这个参数是一个用户的名字。最后handle调用了触发处理请求的服务对象。
WSDL模式客户端
客户端代码如下
PLAIN TEXTPHP:
try {
$client = new SoapClient(’hello.wsdl’);
$result = $client->__soapCall(’greet’, array(array(’name’ => ‘Sam’)));
printf(”Result = %s/n”, $result->greetReturn);
} catch (Exception $e) {
printf(”Message = %s/n”,$e->__toString());
}
?>
客户端代码中,首先创建一个使用WSDL文件作参数的SoapClient实例。接着__soapCall()调用作为参数传入它的操作,也就是greet和传入操作的参数。
请求和响应
当你将上述的PHP脚本放在你web服务器目录下的文档中,并利用WEB浏览器或在PHP解析器的命令行调用脚本,客户端发送一个SOAP请求到服务端脚本,服务端将向客户端发送一个SOAP响应来响应客户端的请求。
上面的SOAP消息都是利用WSDL模式的服务端和客户端来获取的。也可以利用non-WSDL模式的服务端和客户端来产生与上面相同的SOAP消息。但是,PHP代码必须有一点改变。下一节会说明如何使用non-WSDL模式。
non-WSDL模式服务端
PLAIN TEXTPHP:
function greet($param) {
$retval = ‘Hello ‘.$param;
return new SoapParam($retval, ‘greetReturn’);
}
$server = new SoapServer(null, array(’uri’ => ‘http://wso2.org/wsf/php/helloService’));
$server->addFunction(’greet’);
$server->handle();
?>
在non -WSDL模式中,想WSDL模式一样首先实现greet函数的功能,但是函数实现的方式跟WSDL模式稍稍有所不同。在non-WSDL模式中,我们必须返回一个SoapParam对象作为响应,而不是一个数组。创建服务时,第一个参数设为null,说明没有提供WSDL;接着传递一个选项作为参数,这个选项参数是服务的URI。最后像WSDL模式一样调用剩下的方法。
non-WSDL模式客户端
PLAIN TEXTPHP:
try {
$client = new SoapClient(null,
array(’location’ => ‘http://localhost/hello/hello_service_nonwsdl.php’,
‘uri’ => ‘http://wso2.org/wsf/php/helloService’));
$result = $client->__soapCall(’greet’, array(new SoapParam(’Sam’, ‘name’))); printf(”Result = %s/n”, $result);
} catch (Exception $e) {
printf(”Message = %s/n”,$e->__toString());
}
?>
在non-WShDL模式中,因为p没有使用WSDL,传递了一个包含服务所在位置和服务URI的参数数组作为参数。然后象WSDL模式中一样调用__soapCall()方法,但是使用了SoapParam类用指定格式打包参数。返回的结果将获取greet中的响应。
结论
这篇文章介绍了SOAP扩展,可以在PHP中通过它来提供和使用Web Services。PHP扩展的强项是它的简单和快速。使用C写的SOAP扩展来运行服务端和客户端是非常简单的。虽然SOAP扩展在处理一些简单的 Web Services时很有用,但是当用它来处理所有的Web Services时就表现出它的局限性。 WSO WSF/PHP就是为了弥补PHP扩展的缺陷而开发的,它是开源的,可以实现SOAP类似的功能并且支持MTOM,WS-Addressing,WS- Security和WS-RelaiableMessaging。WSO2 WSF/PHP 支持与SOAP扩展类似的API。
这是php soap的一些介绍。我写的实例明天在贴出。忙着看地震报道。

php开发的七种武器之一长生剑pdo

May 13, 2008 php No Comments
现在企业越来越多用php做开发,当社会上培训java的求职者泛滥时,尤其显出phper的需求空缺。今天讲解php做web开发的的七种武器篇,涉及web开发全过程,以供初学者学习。
做web开发很重要的一块时和数据库打交道。所以数据库的连接层很重要。以前在面向过程开发时候自己写mysql_connect() 链接数据库,后来自己用类封装mysql_connect(),最后有一些开源的db类库,如adodb,pdo,pear:db,phplib,mdb等等。自己比较喜欢adodb。但是在zend framework中用的是pdo,只好又用起pdo了。感觉pdo也蛮好的。毕竟pdo是官方的。今天来说说pdo吧,我把他列在七种武器之首,长生剑,也显出对这块的偏爱,古代侠客都喜爱剑。兵器首选吧!
那pdo是什么呢?先看看php manual怎么介绍的,The PHP Data Objects (PDO) extension defines a lightweight, consistent interface for accessing databases in PHP.PHP6中将默认识用PDO连接数据库,所有非PDO扩展将会在PHP6被从扩展中移除。该扩展提供PHP内置类 PDO来对数据库进行访问,不同数据库使用相同的方法名,解决数据库连接不统一的问题。
第一:安装PDO
我这里是WINDOWS下开发用的PDO扩展,php5.1以及以后版本的程序包里已经带了;php5.0.x则要到pecl.php.net下载,放到你的扩展库,就是PHP所在的文件夹的ext文件夹下;
配置:
修改你的php.ini配置文件,使它支持pdo.(以前在zend framework开发篇也介绍过的)。
把extension=php_pdo.dll前面的分号去掉,
往下还有
;extension=php_pdo.dll
;extension=php_pdo_firebird.dll
;extension=php_pdo_informix.dll
;extension=php_pdo_mssql.dll
;extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_oci8.dll
;extension=php_pdo_odbc.dll
;extension=php_pdo_pgsql.dll
;extension=php_pdo_sqlite.dll
各扩展所对应的数据库是:
Driver name Supported databases
PDO_DBLIB FreeTDS / Microsoft SQL Server / Sybase
PDO_FIREBIRD Firebird/Interbase 6
PDO_INFORMIX IBM Informix Dynamic Server
PDO_MYSQL MySQL 3.x/4.x
PDO_OCI Oracle Call Interface
PDO_ODBC ODBC v3 (IBM DB2, unixODBC and win32 ODBC)
PDO_PGSQL PostgreSQL
PDO_SQLITE SQLite 3 and SQLite 2

你要使用哪种数据库,只要把相应的扩展前的注释符号”;”去掉就可以了。

第二:使用PDO
pdo的类是这样的。
class PDO {
__construct ( string $dsn [, string $username [, string $password [, array $driver_options ]]] )
bool beginTransaction ( void )
bool commit ( void )
string errorCode ( void )
array errorInfo ( void )
int exec ( string $statement )
mixed getAttribute ( int $attribute )
array getAvailableDrivers ( void )
string lastInsertId ([ string $name ] )
PDOStatement prepare ( string $statement [, array $driver_options ] )
PDOStatement query ( string $statement )
string quote ( string $string [, int $parameter_type ] )
bool rollBack ( void )
bool setAttribute ( int $attribute , mixed $value )
}
我们通过下面的例子来分析PDO连接数据库,我用的是mysql。

$dbms='mysql'; //数据库类型 Oracle 用ODI,对于开发者来说,使用不同的数据库,只要改这个,不用记住那么多的函数了
$host='localhost'; //数据库主机名
$dbName='test'; //使用的数据库
$user='root'; //数据库连接用户名
$pass=''; //对应的密码
$dsn="$dbms:host=$host;dbname=$dbName";
//

try {
$db = new PDO($dsn, $user, $pass); //初始化一个PDO对象,就是创建了数据库连接对象$db
echo "连接成功
“;
/*你还可以进行一次搜索操作
foreach ($dbh->query(’SELECT * FROM user) as $row) {
print_r($row); //你可以用 echo($GLOBAL); 来看到这些值
}
*/
$db = null;
} catch (PDOException $e) {
die (”Error!: ” . $e->getMessage() . “
“);
}
//默认这个不是长连接,如果需要数据库长连接,需要最后加一个参数:array(PDO::ATTR_PERSISTENT => true) 变成这样:
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
?>
查询数据,上面我们已经进行了一次查询,我们还可以使用如下的查询:
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); //设置属性
$rs = $db->query(”SELECT * FROM user”);
$rs->setFetchMode(PDO::FETCH_ASSOC);
$result_arr = $rs->fetchAll();
print_r($result_arr);
?>
以上因为用到setAttribute()方法,放上那两个参数,把字段名强制转换成小写。下面列出多有PDO::setAttribute()的参数:

PDO::ATTR_CASE: 强制列名变成一种格式,详细如下(第二个参数):
PDO::CASE_LOWER: 强制列名是小写.
PDO::CASE_NATURAL: 列名按照原始的方式
PDO::CASE_UPPER: 强制列名为大写.

PDO::ATTR_ERRMODE: 错误提示.

PDO::ERRMODE_SILENT: 不显示错误信息,只显示错误码.
PDO::ERRMODE_WARNING: 显示警告错误.
PDO::ERRMODE_EXCEPTION: 抛出异常.

PDO::ATTR_ORACLE_NULLS (不仅仅是ORACLE有效,别的数据库也有效): )指定数据库返回的NULL值在php中对应的数值。

PDO::NULL_NATURAL: 不变.
PDO::NULL_EMPTY_STRING: Empty string is converted to NULL.
PDO::NULL_TO_STRING: NULL is converted to an empty string.
PDO::ATTR_STRINGIFY_FETCHES: Convert numeric values to strings when fetching. Requires bool.

PDO::ATTR_STATEMENT_CLASS: Set user-supplied statement class derived from PDOStatement. Cannot be used with persistent PDO instances. Requires array(string classname, array(mixed constructor_args)).
PDO::ATTR_AUTOCOMMIT (available in OCI, Firebird and MySQL): Whether to autocommit every single statement.

PDO::MYSQL_ATTR_USE_BUFFERED_QUERY (available in MySQL): Use buffered queries.

例子中的$rs->setFetchMode(PDO::FETCH_ASSOC);是PDOStatement::setFetchMode(),对返回类型的声明。
有如下:
PDO::FETCH_ASSOC — 关联数组形式
PDO::FETCH_NUM — 数字索引数组形式
PDO::FETCH_BOTH — 两者数组形式都有,这是缺省的
PDO::FETCH_OBJ — 按照对象的形式,类似于以前的 mysql_fetch_object()
插入,更新,删除数据,
$db->exec(”DELETE FROM user where id=1″);
简单的总结一下上面的操作:

查询操作主要是PDO::query()、PDO::exec()、PDO::prepare()。
PDO::query()主要是用于有记录结果返回的操作,特别是SELECT操作,
PDO::exec()主要是针对没有结果集合返回的操作,比如INSERT、UPDATE、DELETE等操作,它返回的结果是当前操作影响的列数。
PDO::prepare()主要是预处理操作,需要通过$rs->execute()来执行预处理里面的SQL语句,这个方法可以绑定参数,功能比较强大,不是本文能够简单说明白的,大家可以参考手册和其他文档。

获取结果集操作主要是:
PDOStatement::fetchColumn(),
PDOStatement::fetch(),
PDOStatement::fetchALL()。
PDOStatement::fetchColumn() 是获取结果指定第一条记录的某个字段,缺省是第一个字段。
PDOStatement::fetch() 是用来获取一条记录,
PDOStatement::fetchAll()是获取所有记录集到一个中,获取结果可以通过PDOStatement::setFetchMode来设置需要结果集合的类型。

另外有两个周边的操作,一个是PDO::lastInsertId()和PDOStatement::rowCount()。PDO::lastInsertId()是返回上次插入操作,主键列类型是自增的最后的自增ID。
PDOStatement::rowCount()主要是用于PDO::query()和PDO::prepare()进行DELETE、INSERT、UPDATE操作影响的结果集,对PDO::exec()方法和SELECT操作无效。

事务和自动提交
至此,您已经通过 PDO 连接到了 mysql,在发出查询之前,您应该理解 PDO 是如何管理事务的。如果之前没有接触过事务,那么首先要知道事务的 4 个特征:原子性(Atomicity)、一致性(Consistency)、独立性(Isolation)和持久性(Durability),即 ACID。用外行人的话说,对于在一个事务中执行的任何工作,即使它是分阶段执行的,也一定可以保证该工作会安全地应用于数据库,并且在工作被提交时,不会受到来自其他连接的影响。事务性工作可以根据请求自动撤销(假设您还没有提交它),这使得脚本中的错误处理变得更加容易。
事务通常是通过把一批更改积蓄起来、使之同时生效而实现的。这样做的好处是可以大大提高这些更新的效率。换句话说,事务可以使脚本更快,而且可能更健壮(不过需要正确地使用事务才能获得这样的好处)。
不幸的是,并不是每种数据库都支持事务(Mysql5支持事务,mysql4我不知道),所以当第一次打开连接时,PDO 需要在所谓的“自动提交(auto-commit)”模式下运行。自动提交模式意味着,如果数据库支持事务,那么您所运行的每一个查询都有它自己的隐式事务,如果数据库不支持事务,每个查询就没有这样的事务。如果您需要一个事务,那么必须使用 PDO::beginTransaction() 方法来启动一个事务。如果底层驱动程序不支持事务,那么将会抛出一个 PDOException(无论错误处理设置是怎样的:这总是一个严重错误状态)。在一个事务中,可以使用 PDO::commit() 或 PDO::rollBack() 来结束该事务,这取决于事务中运行的代码是否成功。
当脚本结束时,或者当一个连接即将被关闭时,如果有一个未完成的事务,那么 PDO 将自动回滚该事务。这是一种安全措施,有助于避免在脚本非正常结束时出现不一致的情况 —— 如果没有显式地提交事务,那么假设有某个地方会出现不一致,所以要执行回滚,以保证数据的安全性。
try {
$db = new PDO(’mysql:host=localhost,dbname=test’, ‘toot’, ‘123456′,
array(PDO_ATTR_PERSISTENT => true));
echo “Connected/n”;
$db->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_EXCEPTION);
$db->beginTransaction();
$db->exec(”insert into user(id, name, pwd) values (1, ‘Joe’, ‘123456′)”);
$db->exec(”insert into userDetail(uid, add, tel)
values (1, ‘上海新闸路’, ‘15555555555′)”);
$db->commit();

} catch (Exception $e) {
$dbh->rollBack();
echo “Failed: ” . $e->getMessage();
}
在上面的示例中,假设我们为一个新用户创建一组条目,这个用户有一个 ID 号,即 1。除了输入这个人的基本数据外,我们还需要记录用户的详细信息。两个更新分别完成起来很简单,但通过将这两个更新包括在 beginTransaction() 和 commit() 调用中,就可以保证在更改完成之前,其他人无法看到更改。如果发生了错误,catch 块可以回滚事务开始以来发生的所有更改,并打印出一条错误消息。

并不是一定要在事务中作出更新。您也可以发出复杂的查询来提取数据,还可以使用那种信息构建更多的更新和查询。当事务在活动时,可以保证其他人在工作进行当中无法作出更改。事实上,这不是 100% 的正确,但如果您之前没有听说过事务的话,这样介绍也未尝不可。

预处理语句和存储过程

很多更成熟的数据库都支持预处理语句的概念。什么是预处理语句?您可以把预处理语句看作您想要运行的 SQL 的一种编译过的模板,它可以使用变量参数进行定制。预处理语句可以带来两大好处:

查询只需解析(或准备)一次,但是可以用相同或不同的参数执行多次。当查询准备好后,数据库将分析、编译和优化执行该查询的计划。对于复杂的查询,这个过程要花比较长的时间,如果您需要以不同参数多次重复相同的查询,那么该过程将大大降低应用程序的速度。通过使用预处理语句,可以避免重复分析/编译/优化周期。简言之,预处理语句使用更少的资源,因而运行得更快。
提供给预处理语句的参数不需要用引号括起来,驱动程序会处理这些。如果应用程序独占地使用预处理语句,那么可以确保没有 SQL 入侵发生。(然而,如果您仍然将查询的其他部分建立在不受信任的输入之上,那么就仍然存在风险)。
预处理语句是如此有用,以致 PDO 实际上打破了在目标 4 中设下的规则:如果驱动程序不支持预处理语句,那么 PDO 将仿真预处理语句。
$sql = 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(’:calories’ => 150, ‘:colour’ => ‘red’));
$red = $sth->fetchAll();
$sth->execute(array(’calories’ => 175, ‘colour’ => ‘yellow’));
$yellow = $sth->fetchAll();
?>
还有一个列子
$sth = $dbh->prepare(’SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->execute(array(150, ‘red’));
$red = $sth->fetchAll();
$sth->execute(array(175, ‘yellow’));
$yellow = $sth->fetchAll();
?>
此外pdo还有两个回馈错误函数,errorCode();errorInfo().

再次感受地震

May 12, 2008 自言堂 No Comments



今天四川汶川发生7.8级地震,今天在上海多个地方也有震动。有些公司都放假了,很多人都感到头晕,晃动。我们公司在三楼没感到,在qq跳出消息才知道发生地震。记得在上初中的时候,在学校遇到一次。也没感觉到。只是大家这样说,后来学校放假回家后都不睡觉。最后也没发生什么。只是那样的经过了。这次上海也没什么,大家说会有余震,大家没睡觉在瞎侃着。看新闻,看到四川震区有学校倒塌,学生被困。默默为他们祈祷,一切都会好的。

vim for window xp

May 12, 2008 兵器谱 No Comments
一直在忍耐我那本本的速度,越来越感觉它的老态龙钟。就一个字,慢。正在考虑换掉它。想用eclipse和zend studio 都不能用,想玩魔兽都不能装。郁闷!

在它下面做开发只好用editplus,其实我也蛮喜欢editplus的,小巧,快速。想起在linux下也有一款类似的软件。vi,就是它。在linux下喜欢用它。相信玩linux都用它吧!。于是觉定在windwos用用。在google搜下还真有这款软件。gvim。下面是一些安装和配置。

第一:下载地址是 http://www.vim.org/download.php#pc 下载windows版本的。

第二:配置 打开C:/Program Files/Vim/_vimrc文件,我的配置是下面代码,主要解决编码问题和喜欢的配色。

set nocompatible
source $VIMRUNTIME/vimrc_example.vim
source $VIMRUNTIME/mswin.vim
behave mswin

set diffexpr=MyDiff()
function MyDiff()
let opt = ‘-a –binary ‘
if &diffopt =~ ‘icase’ | let opt = opt . ‘-i ‘ | endif
if &diffopt =~ ‘iwhite’ | let opt = opt . ‘-b ‘ | endif
let arg1 = v:fname_in
if arg1 =~ ‘ ‘ | let arg1 = ‘”‘ . arg1 . ‘”‘ | endif
let arg2 = v:fname_new
if arg2 =~ ‘ ‘ | let arg2 = ‘”‘ . arg2 . ‘”‘ | endif
let arg3 = v:fname_out
if arg3 =~ ‘ ‘ | let arg3 = ‘”‘ . arg3 . ‘”‘ | endif
let eq = ”
if $VIMRUNTIME =~ ‘ ‘
if &sh =~ ‘/<cmd’
let cmd = ‘”"‘ . $VIMRUNTIME . ‘/diff”‘
let eq = ‘”‘
else
let cmd = substitute($VIMRUNTIME, ‘ ‘, ‘” ‘, ”) . ‘/diff”‘
endif
else
let cmd = $VIMRUNTIME . ‘/diff’
endif
silent execute ‘!’ . cmd . ‘ ‘ . opt . arg1 . ‘ ‘ . arg2 . ‘ > ‘ . arg3 . eq
endfunction


” 不同中文编码显示
” 同时支持GBK和UTF-8编码

“set fileencoding=gb18030
“set fileencodings=utf-8,gb18030,utf-16,big5
set fileencodings=ucs-bom,utf-8,cp936
set fileencoding=utf-8
set encoding=cp936 “set encoding=utf-8


” 设置字体

set guifont=Lucida_Console:h14:cANSI


” 启动最大化, 设置颜色方案

” winsize 1024 768
au GUIEnter * simalt ~x
colorscheme desert


“自动缩进

set autoindent


” 设置tab制表符为4个空格

set ts=4
set expandtab
set shiftwidth=4
set cinoptions=>4,e0,n0,f0,{0,}0,^0,:s,=s,l0,gs,hs,ps,ts,+s,c3,C0,(2s,us,
/U0,w0,m0,j0,)20,*30

“set cindent



” 展开显示文件类型菜单

let do_syntax_sel_menu = 1 | runtime! synmenu.vim | aunmenu &Syntax.&Show/ filetypes/ in/ menu


” 设置语法

“if &filetype != ‘javacc’
“ setlocal filetype=javacc
“endif
“set syntax=javacc
“cal SetSyn(”cpp”)
“cal SetSyn(”vb”)
“cal SetSyn(”perl”)
“cal SetSyn(”awk”)


” 备份文件放在指定目录

set backupdir=C:/tmp


” 没有警告音和视觉警告

set vb t_vb=


” 禁用swf交换文件

setlocal noswapfile


” 显示行号

set number


” 隐藏工具条

” see :help ‘guioptions’

set guioptions-=T
“set guioptions-=m


” 状态条,显示字节数,列数,行数,当前行等信息

set statusline=%F%m%r%h%w/ [FORMAT=%{&ff}]/ [TYPE=%Y]/ [ASCII=/%03.3b]/ [HEX=/%02.2B]/ [POS=%04l,%04v][%p%%]/ [LEN=%L]
set laststatus=2 ” always show the status line


“auto-comments for // and /* */
“setlocal comments=sO:*/ -,mO:*/ / ,exO:*/,s1:/*,mb:*,ex:*/,://

“disable auto-comments for //
“setlocal comments=sO:*/ -,mO:*/ / ,exO:*/,s1:/*,mb:*,ex:*/,f://

“disable auto-comments for // and /* */

“setlocal comments=sO:*/ -,mO:*/ / ,exO:*/,s1:/*
setlocal comments=”"
试试吧,用vim开发蛮爽的。感觉一定不一样。

php memcached 的安装与使用

May 9, 2008 memcached No Comments
今天讲讲如何解决网站的高负荷的并发链接请求问题。现在b/s结构的网站大多数的架构是这样的。(以我的上一个项目为例)。

1台file系统储存公共文件,3台db(其中1台master,2台slave,做到读写分离),4台web。最外层还有负载均衡。这样的架构在访问高峰期还是很慢。最多的原因是数据库查询的时候消耗的资源。数据库的反复查询,数据来返很慢。造成用户体验很差。今天讲的是用memcached来缓存经常查询的数据和消耗大数据。

现在大知道memcached是做什么的吧!Memcached是分布式的,也就是说它不是本地的。它基于网络连接(当然它也可以使用localhost)方式完成服务,本身它是一个独立于应用的程序或守护进程(Daemon方式)。
用它还可以很好的解决分布式问题。说白了,就是拿出一块内存用来存放数据,供用户读取,因为内存的速度是很快的。

不多说了,来点实际的吧。下面是memcached的安装,分linux系统和windows系统。

第一:windows下安装

直接从官方网站即可下载到 memcached-1.1.12.tar.gz。除此之外,memcached 用到了 libevent下载的是 libevent-1.1a.tar.gz

接下来是分别将 libevent-1.1a.tar.gz 和 memcached-1.1.12.tar.gz 解开包、编译、安装:

# tar -xzf libevent-1.1a.tar.gz # cd libevent-1.1a # ./configure –prefix=/usr # make # make install # cd .. # tar -xzf memcached-1.1.12.tar.gz # cd memcached-1.1.12 # ./configure –prefix=/usr # make # make install

安装完成之后,memcached 应该在 /usr/bin/memcached。

/usr/bin/memcached -d -m 10 -u root -l 192.168.40.4 -p 12000 -c 256 -P /tmp/memcached.pid

参数说明:
-d选项是启动一个守护进程
-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB
-u是运行Memcache的用户,我这里是root
-l是监听的服务器IP地址
-p是设置Memcache监听的端口,最好是1024以上的端口
-c选项是最大运行的并发连接数,默认是1024,按照你服务器的负载量来设定
-P是设置保存Memcache的pid文件

php编译带上–enable-memcache[=DIR] 选项

第二:windows下安装

memcached win32http://jehiah.cz/projects/memcached-win32/

选择下载binaries版本,解压缩安装。

memcached -d install

memcached -d start

再下载pecl包,http://cn.php.net/get/pecl-5.2.6-Win32.zip/from/a/mirror

解压,将php_memcache.dll复制到C:/php/ext,在打开C:/WINDOWS下的php.ini加入此行

extension=php_memcache.dll

重启apache,测试下。

以下是memcached常用的函数。


connect($ip,$port);memcached链接。


add ($key, $val, $exp = 0)

往 memcached 中写入对象,$key 是对象的唯一标识符,$val 是写入的对象数据,$exp 为过期时间,单位为秒,默认为不限时间;

get ($key)

从 memcached 中获取对象数据,通过对象的唯一标识符 $key 获取;

replace ($key, $value, $exp=0)

使用 $value 替换 memcached 中标识符为 $key 的对象内容,参数与 add() 方法一样,只有 $key 对象存在的情况下才会起作用;

delete ($key, $time = 0)

删除 memcached 中标识符为 $key 的对象,$time 为可选参数,表示删除之前需要等待多长时间。

<?php
$mem = new memcache();
$mem->connect(’localhost’, 11211) or die (”Could not connect”);
$string = “this is memcached!”;
$replace = ‘i replace you’;
$key = ’show’;
$exp = 3600;
$mem->set($key,$string,$exp);
$mem->delete($key,0);
$mem->replace($key,$replace,$exp);
echo $mem->get($key);
?>

测试下是不是比以前快了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐