Showing posts with label PHP. Show all posts
Showing posts with label PHP. Show all posts

Monday, April 11, 2011

PHP邮件发送验证功能 | 皮特博客

PHP邮件发送验证功能 | 皮特博客:

第一步:建立数据库
把下面数据库复制粘贴在一个记事本,然后在PHPMyAdmin创建一个新的数据库并导入下面数据。
– 表的结构 `registered_members`
–
CREATE TABLE `registered_members` (
`id` int(4) NOT NULL auto_increment,
`name` varchar(65) NOT NULL default ”,
`email` varchar(65) NOT NULL default ”,
`password` varchar(65) NOT NULL default ”,
`country` varchar(65) NOT NULL default ”,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
–
– 导出表中的数据 `registered_members`
–
– ——————————————————–
–
– 表的结构 `temp_members_db`
–
CREATE TABLE `temp_members_db` (
`confirm_code` varchar(65) NOT NULL default ”,
`name` varchar(65) NOT NULL default ”,
`email` varchar(65) NOT NULL default ”,
`password` varchar(15) NOT NULL default ”,
`country` varchar(65) NOT NULL default ”
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
–
– 导出表中的数据 `temp_members_db`
–
第二步:建立数据库连接
请把下面代码复制到你的文本编编译器里面,并命名:config.php
$host=”Hostname”; // Host name
$username=”Username”; // Mysql username
$password=”Password”; // Mysql password
$db_name=”DB name”; // Database name
//Connect to server and select database.
mysql_connect(“$host”, “$username”, “$password”)or die(“cannot connect to server”);
mysql_select_db(“$db_name”)or die(“cannot select DB”);
?>
第三步:注册页面
请把下面代码复制到你的文本编辑器里面,并命名:signup.php


注册
用户名 :
邮箱 :
密码 :
国家 :



第四步:数据插入到数据和邮件发送
请把下面代码复制到你的文本编辑器里面,并命名:signup_ac.php
// table name
$tbl_name=temp_members_db;
// Random confirmation code
$confirm_code=md5(uniqid(rand()));
// values sent from form
$name=$_POST['name'];
$email=$_POST['email'];
$country=$_POST['country'];
// Insert data into database
$sql=”INSERT INTO $tbl_name(confirm_code, name, email, password, country)VALUES(‘$confirm_code’, ‘$name’, ‘$email’, ‘$password’, ‘$country’)”;
$result=mysql_query($sql);
// if suceesfully inserted data into database, send confirmation link to email
if($result){
// —————- SEND MAIL FORM —————-
// send e-mail to …
$to=$email;
// Your subject
$subject=”Your confirmation link here”;
// From
$header=”from: your name ”;
// Your message
$message=”Your Comfirmation link \r\n”;
$message.=”Click on this link to activate your account \r\n”;
$message.=”http://www.yourweb.com/confirmation.php?passkey=$confirm_code”;
// send email
$sentmail = mail($to,$subject,$message,$header);
}
// if not found
else {
echo “Not found your email in our database”;
}
// if your email succesfully sent
if($sentmail){
echo “Your Confirmation link Has Been Sent To Your Email Address.”;
}
else {
echo “Cannot send Confirmation link to your e-mail address”;
}
?>
第五步:验证
请把下面代码复制到你的文本编辑器里面,并命名:confirmation.php
// Passkey that got from link
$passkey=$_GET['passkey'];
$tbl_name1=”temp_members_db”;
// Retrieve data from table where row that match this passkey
$sql1=”SELECT * FROM $tbl_name1 WHERE confirm_code =’$passkey’”;
$result1=mysql_query($sql1);
// If successfully queried
if($result1){
// Count how many row has this passkey
$count=mysql_num_rows($result1);
// if found this passkey in our database, retrieve data from table “temp_members_db”
if($count==1){
$rows=mysql_fetch_array($result1);
$name=$rows['name'];
$email=$rows['email'];
$password=$rows['password'];
$country=$rows['country'];
$tbl_name2=”registered_members”;
// Insert data that retrieves from “temp_members_db” into table “registered_members”
$sql2=”INSERT INTO $tbl_name2(name, email, password, country)VALUES(‘$name’, ‘$email’, ‘$password’, ‘$country’)”;
$result2=mysql_query($sql2);
}
// if not found passkey, display message “Wrong Confirmation code”
else {
echo “Wrong Confirmation code”;
}
// if successfully moved data from table”temp_members_db” to table “registered_members” displays message “Your account has been activated” and don’t forget to delete confirmation code from table “temp_members_db”
if($result2){
echo “Your account has been activated”;
// Delete information of this user from table “temp_members_db” that has this passkey
$sql3=”DELETE FROM $tbl_name1 WHERE confirm_code = ‘$passkey’”;
$result3=mysql_query($sql3);
}
}
?>
注意:
如果没有邮箱服务器的,会出现如下面提示之类的东西:
Warning: mail() [function.mail]: Failed to connect to mailserver at “localhost” port 25, verify your “SMTP” and “smtp_port” setting in php.ini or use ini_set() in E:\wamp\www\mailverification\signup_ac.php on line 39
Cannot send Confirmation link to your e-mail address
不用慌,这说明你的数据已经被写进数据库了。
你可以用以下方法去通过验证:
先复制这个URL到你的浏览器:http://www.你的网站.com/confirmation.php?passkey=
然后到你的数据库里面把confirm_code复制粘贴在passkey=后面,并回车,会出现提示的:Your account has been activated!
恭喜你了!你的邮件验证系统就完成了!如果有什么问题的,欢迎随时留言,回以最快的速度解决你的问题。由于时间关系,英文就不做翻译了。

Zend_Form Check For Existing Email Address In Database

Zend_Form Check For Existing Email Address In Database

If you’re coding a registration form you will either want to check if a username or an email address is already present in the database. This is very easy to do, assuming you are familiar with using Zend_Form:



That’s all. NOTE: This might be obvious but you cannot chain the setMessage(…) function directly to the end of new Zend_Validate_Db_NoRecordExists(‘user’, ‘email’); 

 If you are unfamiliar Zend_Form, here’s a full example:

Password confirmation using Zend Form and Validators | Thoughts, Codes and Games

Password confirmation using Zend Form and Validators | Thoughts, Codes and Games

A while back i needed a password confirmation field for my users. I looked and found this neat little snippet. I cant remember who created it originally so i cant give credits to the person but its quite easy to use. Just add this to your library and create a new validator object like this.
class App_Validate_PasswordConfirmation extends Zend_Validate_Abstract {
const NOT_MATCH = 'notMatch';
protected $_messageTemplates = array(
self::NOT_MATCH => 'Password confirmation does not match'
);
public function isValid($value, $context = null) {
$value = (string) $value;
$this->_setValue($value);
if (is_array($context)) {
if (
isset($context['password_confirm']) &&
($value == $context['password_confirm'])) {
return true;
}
} elseif (is_string($context) && ($value == $context)) {
return true;
}
$this->_error(self::NOT_MATCH);
return false;
}
}
This would be in your form where you want to have password confirmation.
$passwordConfirmation = new App_Validate_PasswordConfirmation();
$password = $this->addElement('password', 'password', array(
'filters' => array('StringTrim'),
'validators' => array(
$passwordConfirmation,
array('Alnum'),
array('StringLength', false, array(6, 100)),
),
'class' => 'input-text',
'required' => true,
'label' => 'Password',
));
$password_confirm = $this->addElement('password', 'password_confirm', array(
'filters' => array('StringTrim'),
'validators' => array(
$passwordConfirmation,
array('Alnum'),
array('StringLength', false, array(6, 100)),
),
'class' => 'input-text',
'required' => true,
'label' => 'Confirm Password',
));
view raw snippet.php This Gist brought to you by GitHub.

Thursday, April 7, 2011

PHP和MYSQL中关于比较两个日期的方法[转]

转自: PHP和MYSQL中关于比较两个日期的方法[转]

PHP和MYSQL中没有像ASP和MSSQL那样有DateDiff这个函数直接比较,MYSQL5.0已经支持DateDiff了,但是4.x还不支持。。。
下面分别来看PHP和MYSQL查询时如何比较。。。

先看PHP:
$date1 = '2008-05-30';
$date2 = '2008-06-05';
$from = mktime(0,0,0,date("m",strtotime($date1)),date("d",strtotime($date1)),date("Y",strtotime($date1)));
$to = mktime(0,0,0,date("m",strtotime($date2)),date("d",strtotime($date2)),date("Y",strtotime($date2)));
$datediff = ($to - $from)/86400;
echo $datediff;
返回值:6

MYSQL就简单地写一条SQL语句就清楚了:
select * from tb where (TO_DAYS(expiredDate)-TO_DAYS(NOW()))<=3 。。。
5.0以上的MYSQL就直接DateDiff了。。。

以下是某人总结的:
30天以内:
mysql> SELECT something FROM table WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;

DAYOFWEEK(date)
返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六)。这些索引值对应于ODBC标准。
mysql> select DAYOFWEEK('1998-02-03');
-> 3

WEEKDAY(date)
返回date的星期索引(0=星期一,1=星期二, ……6= 星期天)。
mysql> select WEEKDAY('1997-10-04 22:23:00');
-> 5
mysql> select WEEKDAY('1997-11-05');
-> 2

DAYOFMONTH(date)
返回date的月份中日期,在1到31范围内。
mysql> select DAYOFMONTH('1998-02-03');
-> 3

DAYOFYEAR(date)
返回date在一年中的日数, 在1到366范围内。
mysql> select DAYOFYEAR('1998-02-03');
-> 34

MONTH(date)
返回date的月份,范围1到12。
mysql> select MONTH('1998-02-03');
-> 2

DAYNAME(date)
返回date的星期名字。
mysql> select DAYNAME("1998-02-05");
-> 'Thursday'

MONTHNAME(date)
返回date的月份名字。
mysql> select MONTHNAME("1998-02-05");
-> 'February'

QUARTER(date)
返回date一年中的季度,范围1到4。
mysql> select QUARTER('98-04-01');
-> 2

WEEK(date)

WEEK(date,first)
对于星期天是一周的第一天的地方,有一个单个参数,返回date的周数,范围在0到52。2个参数形式WEEK()允许你指定星期是否开始于星期天或星期一。如果第二个参数是0,星期从星期天开始,如果第二个参数是1,
从星期一开始。
mysql> select WEEK('1998-02-20');
-> 7
mysql> select WEEK('1998-02-20',0);
-> 7
mysql> select WEEK('1998-02-20',1);
-> 8

YEAR(date)
返回date的年份,范围在1000到9999。
mysql> select YEAR('98-02-03');
-> 1998

HOUR(time)
返回time的小时,范围是0到23。
mysql> select HOUR('10:05:03');
-> 10

MINUTE(time)
返回time的分钟,范围是0到59。
mysql> select MINUTE('98-02-03 10:05:03');
-> 5

SECOND(time)
回来time的秒数,范围是0到59。
mysql> select SECOND('10:05:03');
-> 3

PERIOD_ADD(P,N)
增加N个月到阶段P(以格式YYMM或YYYYMM)。以格式YYYYMM返回值。注意阶段参数P不是日期值。
mysql> select PERIOD_ADD(9801,2);
-> 199803

PERIOD_DIFF(P1,P2)
返回在时期P1和P2之间月数,P1和P2应该以格式YYMM或YYYYMM。注意,时期参数P1和P2不是日期值。
mysql> select PERIOD_DIFF(9802,199703);
-> 11

DATE_ADD(date,INTERVAL expr type)

DATE_SUB(date,INTERVAL expr type)

ADDDATE(date,INTERVAL expr type)

SUBDATE(date,INTERVAL expr type)
这些功能执行日期运算。对于MySQL 3.22,他们是新的。ADDDATE()和SUBDATE()是DATE_ADD()和DATE_SUB()的同义词。
在MySQL 3.23中,你可以使用+和-而不是DATE_ADD()和DATE_SUB()。(见例子)date是一个指定开始日期的 DATETIME或DATE 值,expr是指定加到开始日期或从开始日期减去的间隔值一个表达式,expr是一个字符串;它可以以一个“-”开始表示负 间隔。type是一个关键词,指明表达式应该如何被解释。EXTRACT(type FROM date)函数从日期中返回“type”间隔。下表显示了 type和expr参数怎样被关联: type值 含义 期望的expr格式
SECOND 秒 SECONDS
MINUTE 分钟 MINUTES
HOUR 时间 HOURS
DAY 天 DAYS
MONTH 月 MONTHS
YEAR 年 YEARS
MINUTE_SECOND 分钟和秒 "MINUTES:SECONDS"
HOUR_MINUTE 小时和分钟 "HOURS:MINUTES"
DAY_HOUR 天和小时 "DAYS HOURS"
YEAR_MONTH 年和月 "YEARS-MONTHS"
HOUR_SECOND 小时, 分钟, "HOURS:MINUTES:SECONDS"
DAY_MINUTE 天, 小时, 分钟 "DAYS HOURS:MINUTES"
DAY_SECOND 天, 小时, 分钟, 秒 "DAYS HOURS:MINUTES:SECONDS"

MySQL在expr格式中允许任何标点分隔符。表示显示的是建议的分隔符。如果date参数是一个DATE值并且你的计算仅仅包含YEAR、MONTH和DAY部分(即,没有时间部分),结果是一个DATE值。否则结果是一个DATETIME值。

mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
-> 1998-01-01 00:00:00
mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
-> 1998-01-01
mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
-> 1997-12-31 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL 1 SECOND);
-> 1998-01-01 00:00:00
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL 1 DAY);
-> 1998-01-01 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL "1:1" MINUTE_SECOND);
-> 1998-01-01 00:01:00
mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
INTERVAL "1 1:1:1" DAY_SECOND);
-> 1997-12-30 22:58:59
mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
INTERVAL "-1 10" DAY_HOUR);
-> 1997-12-30 14:00:00
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
-> 1997-12-02
mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
-> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
-> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
-> 20102

如果你指定太短的间隔值(不包括type关键词期望的间隔部分),MySQL假设你省掉了间隔值的最左面部分。
如果你指定一个type是 DAY_SECOND,值expr被希望有天、小时、分钟和秒部分。如果你象"1:10"这样指定值,MySQL假设 日子和小时部分是丢失的并且值代表分钟和秒。换句话说,"1:10" DAY_SECOND以它等价于"1:10" MINUTE_SECOND 的方式 解释,这对那MySQL解释TIME值表示经过的时间而非作为一天的时间的方式有二义性。如果你使用确实不正确的日期,结果是NULL。如果你增 加 MONTH、YEAR_MONTH或YEAR并且结果日期大于新月份的最大值天数,日子在新月用最大的天调整。

mysql> select DATE_ADD('1998-01-30', Interval 1 month);
-> 1998-02-28

注意,从前面的例子中词INTERVAL和type关键词不是区分大小写的。
TO_DAYS(date)
给出一个日期date,返回一个天数(从0年的天数)。
mysql> select TO_DAYS(950501);
-> 728779
mysql> select TO_DAYS('1997-10-07');
-> 729669

TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。

FROM_DAYS(N)
给出一个天数N,返回一个DATE值。
mysql> select FROM_DAYS(729669);
-> '1997-10-07'

TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。

DATE_FORMAT(date,format)
根据format字符串格式化date值。下列修饰符可以被用在format字符串中:
%M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。)
%Y 年, 数字, 4 位
%y 年, 数字, 2 位
%a 缩写的星期名字(Sun……Sat)
%d 月份中的天数, 数字(00……31)
%e 月份中的天数, 数字(0……31)
%m 月, 数字(01……12)
%c 月, 数字(1……12)
%b 缩写的月份名字(Jan……Dec)
%j 一年中的天数(001……366)
%H 小时(00……23)
%k 小时(0……23)
%h 小时(01……12)
%I 小时(01……12)
%l 小时(1……12)
%i 分钟, 数字(00……59)
%r 时间,12 小时(hh:mm:ss [AP]M)
%T 时间,24 小时(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM
%w 一个星期中的天数(0=Sunday ……6=Saturday )
%U 星期(0……52), 这里星期天是星期的第一天
%u 星期(0……52), 这里星期一是星期的第一天
%% 一个文字“%”。

所有的其他字符不做解释被复制到结果中。

mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
-> 'Saturday October 1997'
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
'%D %y %a %d %m %b %j');
-> '4th 97 Sat 04 10 Oct 277'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
'%H %k %I %r %T %S %w');
-> '22 22 10 10:23:00 PM 22:23:00 00 6'
MySQL3.23中,在格式修饰符字符前需要%。在MySQL更早的版本中,%是可选的。

TIME_FORMAT(time,format)
这象上面的DATE_FORMAT()函数一样使用,但是format字符串只能包含处理小时、分钟和秒的那些格式修饰符。其他修饰符产生一个NULL值或0。
CURDATE()

CURRENT_DATE
以'YYYY-MM-DD'或YYYYMMDD格式返回今天日期值,取决于函数是在一个字符串还是数字上下文被使用。
mysql> select CURDATE();
-> '1997-12-15'
mysql> select CURDATE() + 0;
-> 19971215

CURTIME()

CURRENT_TIME
以'HH:MM:SS'或HHMMSS格式返回当前时间值,取决于函数是在一个字符串还是在数字的上下文被使用。
mysql> select CURTIME();
-> '23:50:26'
mysql> select CURTIME() + 0;
-> 235026

NOW()

SYSDATE()

CURRENT_TIMESTAMP
以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回当前的日期和时间,取决于函数是在一个字符串还是在数字的
上下文被使用。
mysql> select NOW();
-> '1997-12-15 23:50:26'
mysql> select NOW() + 0;
-> 19971215235026

UNIX_TIMESTAMP()

UNIX_TIMESTAMP(date)
如果没有参数调用,返回一个Unix时间戳记(从'1970-01-01 00:00:00'GMT开始的秒数)。如果UNIX_TIMESTAMP()用一
个date参数被调用,它返回从'1970-01-01 00:00:00' GMT开始的秒数值。date可以是一个DATE字符串、一个DATETIME
字符串、一个TIMESTAMP或以YYMMDD或YYYYMMDD格式的本地时间的一个数字。
mysql> select UNIX_TIMESTAMP();
-> 882226357
mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
-> 875996580

当UNIX_TIMESTAMP被用于一个TIMESTAMP列,函数将直接接受值,没有隐含的“string-to-unix-timestamp”变换。

FROM_UNIXTIME(unix_timestamp)
以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回unix_timestamp参数所表示的值,取决于函数是在一个字符串
还是或数字上下文中被使用。
mysql> select FROM_UNIXTIME(875996580);
-> '1997-10-04 22:23:00'
mysql> select FROM_UNIXTIME(875996580) + 0;
-> 19971004222300

FROM_UNIXTIME(unix_timestamp,format)
返回表示 Unix 时间标记的一个字符串,根据format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条
目同样的修饰符。
mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x');
-> '1997 23rd December 03:43:30 x'

SEC_TO_TIME(seconds)
返回seconds参数,变换成小时、分钟和秒,值以'HH:MM:SS'或HHMMSS格式化,取决于函数是在一个字符串还是在数字
上下文中被使用。
mysql> select SEC_TO_TIME(2378);
-> '00:39:38'
mysql> select SEC_TO_TIME(2378) + 0;
-> 3938

TIME_TO_SEC(time)
返回time参数,转换成秒。
mysql> select TIME_TO_SEC('22:23:00');
-> 80580
mysql> select TIME_TO_SEC('00:39:38');
-> 2378

Tuesday, April 5, 2011

PHP中如何保存变量,一遍刷新后仍然可以使用

PHP中如何保存变量,一遍刷新后仍然可以使用 - ItEye问答

session_start(); //这句话要放在这里,因为每一次访问session都必须执行。
if(isset($_GET['vtag'])){
$_SESSION['vtag']=$_GET['vtag'];
$gettag=$_GET['vtag']; //这里多了个引号。。。。
echo "欢迎光临".$gettag;
}
elseif(isset ($_SESSION['vtag'])){ //这里要括起来
$gettag=$_SESSION['vtag'];
echo "欢迎再次光临".$gettag;
}
else{
echo "非法访问";
exit;
}

And for Zend:
Zend_Session::Start();
$language =new Zend_Session_Namespace('langugae');

if (isset($_GET['lang'])){
$language->lang = $_GET['lang'];
$lo = $_GET['lang'];
}elseif (isset($language->lang)) {
$lo = $language->lang;
}

    Monday, April 4, 2011

    Zend_Session会话处理实例详解(一)_ZEND中国_百度空间

    Zend_Session会话处理实例详解(一)_ZEND中国_百度空间

    在计算机语言中,会话是一种面向连接的可靠通信方式。而会话处理机制,即是指编程语言实现基于会话的通信的方式。在PHP中,会话(session)代表服务器端与客户端之间的一种持久的状态数据。使用ZendFramework的Session可以在由相同客户端发起的多个页面请求之间,管理和保护会话数据。本章介绍如何使用Zend_Session组件来实现会话的处理。
    1 Zend_Session会话简介
    正如本章引言所说的,会话的本质是一种数据,它代表着服务器与客户端之间的一种状态。例如,论坛登录的用户数据、用户的登录时间、正在浏览的页面等都属于会话的范畴。在Zend_Session中的会话数据是对Cookie数据的扩展。但该数据又与Cookie数据有所不同。二者最明显的区别就是会话数据不储存在客户端,而Cookie则通常保存在客户端。会话数据仅在服务器端源代码使用时,才通过回应客户端的请求与客户端共享会话数据。
    在Zend_Session组件中,“session data”代表存储在服务器端的$_SESSION数组中的数据。该数据使用Zend_Session来管理,由会话命名空间(Zend_Session_Namespace,该类为Zend_Session的一个子类)以对象的方式来控制。命名空间逻辑上就是一系列以字符串为键名的联合数组,这类似于普通的PHP数组。
    Zend_Session_Namespace的实例用对象存储的方式实现了$_SESSION的命名空间。Zend_Session组件封装了PHP内置的会话模块,同时还提供了一个管理会话的接口,而且也为Zend_Session_Namespace 持久化命名空间数据提供了API。
    Zend_Session_Namespace为会话命名空间数据到PHP内部会话机制的持久化提供了一个标准的、面向对象的接口。Zend_Session支持现有无名的会话,同时也支持“登录会话”(提供用户名与密码的会话)。因为Zend_Session使用了PHP内置的会话函数,所以常用的配置选项和设置都仍然适用。正因为如此,储存在cookie或者URL中的会话标识,会保持客户端与服务器端会话状态数据之间的联系。
    2 Zend_Session基本用法
    上一节对Zend_Session做了一个纯理论性的简介。本节将以具体的实例来讲解Zend_Session的基本用法。其中包括如何使用Zend_Session实现会话、如何对会话命名空间进行迭代以及如何对会话命名空间进行访问。
    2.1 使用Zend_Session
    本小节来介绍如何使用Zend_Session实现会话。要使用Zend_Session会话,应该需要以下几个步骤。
    (1)引用命名空间(Zend_Session_Namespace)类。
    (2)为命名空间类实例化一个对象。可以使用new关键字为类实例化对象,其中要使用参数命名空间。如果不指定参数,则类的构造函数会使用默认的命名空间参数,其值为Default。
    (3)使用Zend_Session_Namespace类的实例的成员,可以对其进行赋值或者读取操作。下面通过一个实例来演示,如何使用Zend_Session实现最基本的会话处理。

    require_once 'Zend/Session/Namespace.php'; //加载Zend_Session_Namespace组件
    $myNamespace=new Zend_Session_Namespace('Myspace'); //为类实例化一个对象
    if(isset($myNamespace->numberOfPageRequests)) //判断指定成员是否有值
    {
    $myNamespace->numberOfPageRequests++; //如果有值则将其累加
    }
    else
    {
    $myNamespace->numberOfPageRequests=1; //如果无值,对其进行赋值操作
    }
    echo "用户的浏览次数为:";
    echo "";

    echo $myNamespace->numberOfPageRequests; //输出获取的对象成员值

    echo "次";
    ?>

    Parse Accept-Language to detect a user's language

    The Future of the Web » Parse Accept-Language to detect a user's language » Web Development with JavaScript, jQuery, PHP and MySQL


    I'm an English-speaking Canadian living in Germany. Quite often I go to a website like Google or Kayak and find myself looking at a German version of the site.
    Okay, I do live in Germany, but why assume that everyone within Germany speaks German? What about visitors from other countries, or even people living here that would prefer to use another language?
    What must be happening is these sites are taking my IP address, looking up the geographical location of that address, and choosing the official language for that country. This may work most of the time, but there is an even easier way to choose a language.
    Most browsers send an Accept-Language header. For example, mine is set to:
    en-ca,en;q=0.8,en-us;q=0.6,de-de;q=0.4,de;q=0.2
    What this basically says is that I prefer (in decreasing order of preference) Canadian English, generic English, US English, German spoken in Germany, and lastly generic German. Any web site I visit is capable of looking at this list and deciding what language I would prefer.
    Of course, no matter what assumptions you make about a visitor, give them a chance to change their language if needed. For example, if you use an Internet cafe in Berlin, you shouldn't be stuck viewing websites in German!
    One really nice thing: I often see Google Ads and other geographically targeted ads in German, and this makes ignoring the ads much easier! :)
    Update: I was inspired to throw together a quick Accept-Language parser in PHP:
    $langs = array();  if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {     // break up string into pieces (languages and q factors)     preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);      if (count($lang_parse[1])) {         // create a list like "en" => 0.8         $langs = array_combine($lang_parse[1], $lang_parse[4]);               // set default to 1 for any without q factor         foreach ($langs as $lang => $val) {             if ($val === '') $langs[$lang] = 1;         }          // sort list based on value          arsort($langs, SORT_NUMERIC);     } }  // look through sorted list and use first one that matches our languages foreach ($langs as $lang => $val) {  if (strpos($lang, 'de') === 0) {   // show German site  } else if (strpos($lang, 'en') === 0) {   // show English site  }  }  // show default site or prompt for language 
    This would produce the following structure for my Accept-Language string:
    Array (     [en-ca] => 1     [en] => 0.8     [en-us] => 0.6     [de-de] => 0.4     [de] => 0.2 )

    ZF组件功能简介

    转自: ZF组件功能简介 - 在网一方的日志 - 网易博客

    Zend_Acl:为权限管理提供轻量并灵活的访问控制列表的功能
    Zend_Auth:为认证和一些通用用例情景的具体认证适配器提供一个接口
    Zend_Cache:一个缓存任何数据的一般方法
    Zend_Captcha:提交数据的验证,以判断提交者是人还是机器自动操作,防止被恶意提交
    Zend_Config:简化访问和使用配置数据
    Zend_Console_Getopt:命令参数的设置和读取
    Zend_Controller:MVC的控制器★★
    Zend_Currency:处理所有关于货币、钱的表示和格式
    Zend_Date:处理日期和时间
    Zend_Db:操作数据库★★
    Zend_Debug:输出变量的值,只有一个方法Zend_Debug::dump($var, $label=null, $echo=true);
    Zend_Dojo:Dojo Toolkit工具,1.6.0版本新增
    Zend_Dom:为使用DOM文档和结构提供工具
    Zend_Exception:ZF抛出的所有异常都是Zend_Exception的子类的对象
    Zend_Feed:处理的RSS和Atom Feed
    Zend_File:处理文件的上传和下载
    Zend_Filter:替换掉不需要不安全的数据★
    Zend_Filter_Input:多重数据过滤和校验★
    Zend_Form:利用ZF多个组件对表单的创建和处理进行简化★
    Zend_Gdata:Google服务的接口○
    Zend_Http:执行HTTP请求,处理GET和POST等
    Zend_Infocard:信息卡认证与管理○
    Zend_Json:处理JS与PHP变量交换
    Zend_Layout:布局,常用于模板,可脱离MVC使用
    Zend_Ldap:处理轻量级目录访问协议,这一组件极不完善
    Zend_Loader:加载的名称是变量的文件,require_once的升级版
    Zend_Locale:本地化和国际化组件(L10n和I18n)
    Zend_Log:通用日志组件,它支持多个日志后端,格式化发送给日志的消息,过滤被纪录的消息
    Zend_Mail:通用功能用于撰写和发送文本以及兼容MIME标准的含有多个段的邮件消息★
    Zend_Measure:处理度量衡的换算
    Zend_Memory:内存数据管理
    Zend_Mime:处理多段MIME消息的辅助类,在Zend_Mail和Zend_Mime_Message中使用了它,也可在需要MIME支持的应用程序中使用
    Zend_OpenId:OpenID的支持接口
    Zend_Paginator:数据分页,或取得所需页的数据★
    Zend_Pdf:加载存在的PDF文档,生成新的、修改和保存修改后的PDF文档
    Zend_ProgressBar:建立和控制进度条的组件
    Zend_Registry:处理对象注册表(通过把对象存储在其中,我们可以在整个项目的任何地方使用同一个对象,相当于一种全局存储)
    Zend_Rest:REST是Web Service的一种,通过XML交换数据
    Zend_Search_Lucene:通用文本搜索引擎,不需要数据库支持
    Zend_Server:基于Reflection API的标准机制,供服务器类开发者使用
    Zend_Service_Akismet:akismet.com的接口○
    Zend_Service_Amazon:amazon.com的接口○
    Zend_Service_Audioscrobbler:audioscrobbler.net的接口○
    Zend_Service_Delicious:del.icio.us的接口○
    Zend_Service_Flickr:flickr.com的接口○
    Zend_Service_Nirvanix:nirvanix.com的接口○
    Zend_Service_ReCaptcha:recaptcha.net的接口○

    Thursday, March 31, 2011

    stdClass的介绍

    一维数组,我现在特别喜欢把它写成对象,因为键盘打起来比较顺手,看起来也顺眼,如
    $andy = array();
    $andy['a'] = 1;
    $andy['b'] = 2;
    $andy['c'] = 3;
    我喜欢把它变成这样
    $andy = array();
    $andy = (object)$andy;
    $andy->a = 1;
    $andy->b = 2;
    $andy->c = 3;
    新建空数组只要$andy = array();
    新建空对像却要$andy = new Andy; 而且还得先有个class Andy{}
    或者得2行
    $andy = array();
    $andy = (object)$andy;
    用array直接改类型成object有点别扭,今天找到了答案,感谢phpx的兄弟

    Monday, January 10, 2011

    几个基于MVC开发的PHP框架介绍 - joan理想人生 - JavaEye技术网站

    转自: 几个基于MVC开发的PHP框架介绍 - joan理想人生 - JavaEye技术网站

    1. Symfony
    Symfony是一个用于开发PHP5项目的web应用框架。
    这个框架的目的在于加速web应用的开发以及维护,减少重复的编码工作。
    Symfony的系统需求不高,可以被轻易的安装在任意设置上:你只需一个Unix或Windows,搭配一个安装了PHP5的网络服务器即可。它与差不多所有的数据库兼容。Symfony的价位不高,相比主机上的花销要低得多。
    对于PHP开发者而言,使用Symfony是一件很自然的事,其学习曲线只有短短一天。干净的设计以及代码可读性将缩短开发时间。开发者可以将敏捷 开发的原理(如DRY,KISS或XP等)应用在其中,将重点放在应用逻辑层面上,而不用花费大量时间在编写没完没了的XML配置文件上。
    Symfony旨在建立企业级的完善应用程序。也就是说,你拥有整个设置的控制权:从路径结构到外部库,几乎一切都可以自定义。为了符合企业的开发条例,Symfony还绑定了一些额外的工具,以便于项目的测试,调试以及归档。
    其官方网站:http://www.symfony-project.org/    
     
    2. QPHP
    QPHP,意为快速PHP,它是一个与ASP.NET类似的MVC框架。基本上它是这样一个情况:
    ◆整合了Java和C#的美感
    ◆除去了在其他PHP框架中使用的Perl形式的意义含糊的语言
    ◆大量基于OOP的概念
    其官方网站:http://qphp.net/
     
    3.Zoop
    Zoop PHP框架,意为Zoop面向对象的PHP框架。这是个稳定,可伸缩并可移植的框架。从诞生到现在的5年间,已经在不少产品开发中被使用。
    Zoop是一个快速,有效并干净的框架。它的伸缩性很好,你可以只安装你需要的功能。
    对代码并不很熟悉的开发者也可以通过Zoop快速的开发安全的web应用。熟练的开发者则可以更加将Zoop的弹性利用到极致。
    Zoop建议将display,logic以及数据层(MVC)分开使用。
    Zoop由很多组件和项目集合而成,其中包括smarty和prototype AJAX框架,PEAR模块等。高效的核心组件提供了很多你原本需要自己编码来实现的功能。Zoop内置的纠错功能可以通过配置实现生产环境下的错误日志 生成,这个错误日志提供了很多信息,可读性很高,可以更轻易的寻找并排除错误。
    Zoop的一个特别之处在于其GuiControls,在PHP中是一个相当革新的想法。它提供了很多form widgets与验证完整的集合到一起,并形成了一个可以轻松打造个性化GuiControls的框架。
    其官方网站:http://zoopframework.com/
     
    4.PHPDevShell
    PHPDevShell是一个开源(GNU/LGPL)的快速应用开发框架,用于开发不含Javascript的纯PHP。它有一个完整的GUI管 理员后台界面。其主要目标在于开发插件一类的基于管理的应用,其中速度、安全、稳定性及弹性是最优先考虑的重点。其设计形成了一个简单的学习曲线,PHP 开发者无需学习复杂的新术语。PHPDevShell的到来满足了开发者们对于一个轻量级但是功能完善,可以无限制的进行配置的GUI的需求。
    其官方网站:http://www.phpdevshell.org/

    Sunday, January 9, 2011

    使用Zend Framework中的 Zend_Pdf来创建pdf文档 - 春哥也编程 - 博客园


    Haru 和 PDFlib 这二个php扩展提供了完整的api来操作pdf文档。
    另外还有很多开源的代码,可以操作pdf。
    这篇文章主要讲解Zend Framework 中的 Zend_Pdf组件。
    Zend_Pdf 是纯PHP实现的一套程序,不依赖于其它的任何外部库文件。
    所以在虚拟主机上用起来是蛮合适的。
    Zend_Pdf 可以对PDF进行绝大部分的操作,比如添加/删除页面,插入文件和图片,
    绘图,更改PDF文档的元信息(update document meta-data)等等。
    下面就以一个简单的例子开始吧:
    setFont($font, 24)
    ->drawText('That which we call a rose,', 72, 720)
    ->drawText('By any other name would smell as sweet.', 72, 620);

    // add page to document
    $pdf->pages[] = $page;

    // save as file
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }

    程序一开始就引入了Zend auto-loader,它会自动include所需的类文件。
    程序其它部分的流程就不解释了,直接看注释就可以明白了。
    drawText函数的后两个参数是初始写入位置的X轴坐标和Y轴坐标。
    注意:Zend_Pdf系统使用 Postscript geometry。也就是说,字体的单位是pt。1pt=1/72 inch;(0,0)原点位于页面的左下脚。

    1.jpg

    值得提一下的是, 通过Zend_Pdf_Font既可以使用内置的14种字体,比如Zend_Pdf_Font::FONT_HELVETICA,也可以使用外部的字体文件。
    看代码:
    setFont($font, 24)
    ->drawText('That which we call a rose,', 72, 720)
    ->drawText('By any other name would smell as sweet.', 72, 620);

    // add page to document
    $pdf->pages[] = $page;

    // save as file
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }

    这个程序与前面的基本相同,只是通过Zend_Pdf_Font::fontWithPath来引入外部字体。
    再多说二句,drawText的第四个参数,可以指定文字的字符集,Zend_Pdf会自动帮你转化成所需的字符集。省得自己用iconv了。
    外部字体文件会被自动压缩,然后嵌入到pdf文件里面,所以生成出来的pdf文件会占用更多的磁盘空间。

    2.jpg

    如果想插入一张图片到pdf文件里面,只需要调用drawImage(),并提供以下参数即可:
    一个Zend_Pdf_Image资源
    图像左下角横坐标
    图像左下角纵坐标
    图像右上角横坐标
    图像右上角纵坐标
    暂时只支持JPEG,PNG,TIFF格式的图片。
    另外:使用JPEG图片的话需要GD库。使用PNG图片的话,需要ZLIB库。
    看代码吧:
    drawImage($image, 50, 50, 400, 400);

    // add page to document
    $pdf->pages[] = $page;

    // save as file
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }

    3.jpg

    上面讲的drawText有一个很大的缺点:文字太长的话,不会自动换行!
    关于这一点,想必用过GD库的imagestring和imagettftext的都深有体会吧。
    幸运的是,Nico Edtinger为Zend_Pdf添加了一个新的功能来解决这个问题。
    http://framework.zend.com/wiki/display/ZFPROP/Zend_Pdf+text+drawing+improvements+-+Nico+Edtinger
    很长的字符串会自动换行,也不会拆开某个单词,而且还可以设置左对齐或者右对齐,实在是很强大的。
    看代码:
    setFont($font, 14);

    // wrap lines of text
    // start at (10,600) and use a block of dimensions 500x500
    $page->drawTextBlock($str, 10, 600, 500, 500, Zend_Pdf_Page::ALIGN_LEFT);

    // wrap lines of text
    // start at (10,500) and use a block of dimensions 200x300
    $page->setFont($font, 20);
    $page->drawTextBlock($str, 10, 500, 200, 300, Zend_Pdf_Page::ALIGN_RIGHT);

    // add page to document
    $pdf->pages[] = $page;

    // save as file
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }
    drawTextBlock参数的说明:
    $page->drawTextBlock($str, 10, 600, 500, 500, Zend_Pdf_Page::ALIGN_LEFT);
    字符串$str,
    起点横坐标10,
    起点纵坐标600,
    文本框的宽度500,
    文本框的高度500,
    选项 Zend_Pdf_Page::ALIGN_LEFT 左对齐。

    4.jpg

    此外,Zend_Pdf提供了一整套的函数来画线,画圆,以及其它图形。
    来看一下画线的例子:
    setFont($font, 10);

    // draw a line at the top of the page
    $page->setLineColor(new Zend_Pdf_Color_Rgb(0,0,0));
    $page->drawLine(10, 790, ($page->getWidth()-10), 790);

    // draw another line near the bottom of the page
    $page->drawLine(10, 25, ($page->getWidth()-10), 25);

    // define image resource
    $image = Zend_Pdf_Image::imageWithPath('logo.jpg');

    // write image to page
    $page->drawImage($image, 25, 800, ($image->getPixelWidth()+25), (800+$image->getPixelHeight()));

    // add footer text
    $page->drawText('Copyright My Company 2010. All rights reserved.', ($page->getWidth()/3), 10);

    // add page to document
    $pdf->pages[] = $page;

    // save as file
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }
    使用drawLine(),提供一下起点和终点的坐标即可画出一条线。
    线条颜色可以使用Zend_Pdf_Page->setLineColor()来控制,它接受一个Zend_Pdf_Color 类型的对象做为参数。可以使用RGB,CMYK,16进制或者HTML颜色来定义Zend_Pdf_Color

    5.jpg

    再来画几个矩形框吧
    setLineColor(new Zend_Pdf_Color_Rgb(0,0,0));

    // draw a face
    $page->drawRectangle(100, 300, 500, 700, Zend_Pdf_Page::SHAPE_DRAW_STROKE);

    // draw the left eye
    $page->setFillColor(new Zend_Pdf_Color_Rgb(255,0,0));
    $page->drawRectangle(150, 600, 200, 650);

    // draw the right eye
    $page->setFillColor(new Zend_Pdf_Color_Rgb(255,0,0));
    $page->drawRectangle(400, 600, 450, 650);

    // draw the nose
    $page->setFillColor(new Zend_Pdf_Color_Rgb(0,255,0));
    $page->drawRectangle(260, 450, 340, 550);

    // draw the mouth
    $page->setFillColor(new Zend_Pdf_Color_Rgb(0,0,255));
    $page->drawRectangle(200, 350, 400, 400);

    // add page to document
    $pdf->pages[] = $page;

    // save as file
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }

    drawRectangle()函数根据提供的左下角坐标和右上角坐标,可以画一个矩形出来。
    最后一个参数描述了这个矩形的样式:outline(stroked),filled or both.
    thesetLineColor()可以定义矩形边框的颜色。setFillColor()可以定义矩形的填充颜色。

    6.jpg

    再来看如何画其它的形状(椭圆,多边形):
    setLineColor(new Zend_Pdf_Color_Rgb(0,0,0));

    // draw a face
    $page->drawRectangle(100, 300, 500, 700, Zend_Pdf_Page::SHAPE_DRAW_STROKE);

    // draw the left eye
    $page->setFillColor(new Zend_Pdf_Color_Rgb(255,0,0));
    $page->drawRectangle(150, 600, 200, 650);

    // draw the right eye
    $page->setFillColor(new Zend_Pdf_Color_Rgb(255,0,0));
    $page->drawRectangle(400, 600, 450, 650);

    // draw the nose
    $page->setFillColor(new Zend_Pdf_Color_Rgb(0,255,0));
    $page->drawCircle(300, 500, 50);

    // draw the mouth
    $page->setFillColor(new Zend_Pdf_Color_Rgb(0,0,255));
    $page->drawEllipse(200, 350, 400, 400);

    // draw a hat
    $page->setFillColor(new Zend_Pdf_Color_Rgb(250,250,0));
    $page->drawPolygon(array(125,300,475), array(700,800,700));

    // add page to document
    $pdf->pages[] = $page;

    // save as file
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }

    drawCircle()是用来画圆的,参数是圆心的坐标和半径。
    drawEllipse()是用来画椭圆的,参数是此椭圆的外接(还是外切?)矩形的左下和右上角坐标。(an ellipse within a rectangular box)
    drawPolygon()是用来画多边形的(n>=3)。第一个参数是所有顶点的X坐标组成的数组。第二个参数是所有顶点的Y坐标组成的数组。

    7.jpg

    再来看另外一个例子,画饼图的:
    $degrees[$y] = ($slices[$y] / $sum) * 360;
    }

    try {
    // create PDF
    $pdf = new Zend_Pdf();

    // create A4 page
    $page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);

    // set font
    $font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);
    $page->setFont($font, 14);

    $lastAngle = 90;
    for ($z=0; $z {
    ///////////////////////////////////////////////////////////////////////////
    ///注:原文中的下面这一段代码不全,我自己补上的。
    ///////////////////////////////////////////////////////////////////////////
    $dx = $dy = 0;
    if (0 <= $lastAngle && $lastAngle< style="word-wrap: break-word; line-height: normal;"> {
    $dy = $radius * sin(deg2rad($lastAngle));
    $dx = $radius * cos(deg2rad($lastAngle));

    }
    elseif (90 <= $lastAngle && $lastAngle< style="word-wrap: break-word; line-height: normal;"> {
    $dy = $radius * sin(deg2rad(180-$lastAngle));
    $dx = -1 * $radius * cos(deg2rad(180-$lastAngle));
    }
    elseif (180 <= $lastAngle && $lastAngle < style="word-wrap: break-word; line-height: normal;"> {
    $dy = -1 * $radius * sin(deg2rad($lastAngle-180));
    $dx = -1 * $radius * cos(deg2rad($lastAngle-180));
    }
    else
    {
    $dy = -1 * $radius * sin(deg2rad(360-$lastAngle));
    $dx = $radius * cos(deg2rad(360-$lastAngle));
    }
    $endX = 250+$dx;
    $endY = 250+$dy;
    /////////////////////////////////////////////////////////////
    /////////补充完毕。
    /////////////////////////////////////////////////////////////
    $page->drawLine(250, 250, $endX, $endY);

    // reset the last angle value
    $lastAngle = $lastAngle + $degrees[$z];
    }

    // draw the circle outline
    $page->drawCircle(250, 250, 100, Zend_Pdf_Page::SHAPE_DRAW_STROKE);

    // add page to document
    $pdf->pages[] = $page;

    // save document
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }

    艾,这个饼图,不知道中间那段计算直角边长的方法有没有办法简化一些。

    8.jpg

    继续吧。
    Zend_Pdf还引入了样式(Style)的概念。
    所谓的样式就是预先定义好的线条颜色,填充颜色,字体之类的集合。
    这个东西最大的好处就是,
    当你在多种不同样式之间切换,一个函数setStyle()就搞定了,
    不用每次都去重新设定线条颜色,填充颜色之类的。
    下面的例子定义了二个样式:cerulean和crimson。然后进行了样式切换。
    setFillColor(new Zend_Pdf_Color_Rgb(0, 161, 224));
    $cerulean->setLineColor(new Zend_Pdf_Color_Rgb(0, 161, 224));
    $cerulean->setLineWidth(5);
    $font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);
    $cerulean->setFont($font, 32);

    // define another style
    $crimson = new Zend_Pdf_Style();
    $crimson->setFillColor(new Zend_Pdf_Color_Rgb(194, 0, 0));
    $crimson->setLineColor(new Zend_Pdf_Color_Rgb(194, 0, 0));
    $crimson->setLineWidth(2);
    $font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES_ROMAN);
    $crimson->setFont($font, 20);

    // write text to page
    // using different styles
    $page->setStyle($cerulean)
    ->drawText('That which we call a rose,', 72, 720);

    $page->setStyle($crimson)
    ->drawText('By any other name would smell as sweet.', 72, 620);

    // add page to document
    $pdf->pages[] = $page;

    // send to browser as download
    header("Content-Disposition: attachment; filename=example.pdf");
    header('Content-Type: application/pdf');
    echo $pdf->render();
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }

    9.jpg

    很多时候,我们需要用table表格来表现一些数据。
    But em,
    Zend_Pdf 不支持直接画table。
    如果我们手绘表格的话,计算量未免太大,一旦要做改动的话,也很难处理。
    幸好,ursh开发了一个非官方的table组件;
    http://sourceforge.net/projects/zendpdftable/
    虽然是beta版的。
    下载之后,扔到Zend Framework的library目录里面。
    看以下的代码:
    '127.0.0.1',
    'username' => 'user',
    'password' => 'pass',
    'dbname' => 'world');

    // configure adapter and query database
    $db = Zend_Db::factory('PDO_MYSQL', $params);
    $stmt = $db->query('SELECT Name, Code, Region FROM country LIMIT 0, 150');

    // create PDF
    $pdf = new My_Pdf_Document('example.pdf', '.');

    // create page
    $page = $pdf->createPage();

    // define font resource
    $font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);

    // set font
    $page->setFont($font, 24);

    // create table
    $table = new My_Pdf_Table(3);

    // iterate over record set
    // set up table content
    while ($record = $stmt->fetch()) {
    $row = new My_Pdf_Table_Row();
    $cols = array();
    foreach ($record as $k => $v) {
    $col = new My_Pdf_Table_Column();
    $col->setText($v);
    $cols[] = $col;
    }
    $row->setColumns($cols);
    $row->setFont($font, 14);
    $row->setBorder(My_Pdf::TOP, new Zend_Pdf_Style());
    $row->setBorder(My_Pdf::BOTTOM, new Zend_Pdf_Style());
    $row->setBorder(My_Pdf:EFT, new Zend_Pdf_Style());
    $row->setCellPaddings(array(10,10,10,10));
    $table->addRow($row);
    }

    // add table to page
    $page->addTable($table, 0, 0);

    // add page to document
    $pdf->addPage($page);

    // save as file
    $pdf->save();
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }

    10.jpg

    也没什么好解释的。

    为多页面的pdf文件创建书签(bookmark,目录)
    就是下面的效果:
    11.jpg

    代码:
    outlines[0] = Zend_Pdf_Outline::create('Table of Contents', null);

    // add pages to document
    // and page links to outline
    for ($x=1; $x<=10; $x++) { $page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4); $pdf->pages[] = $page;
    $destination{$x} = Zend_Pdf_Destination_Fit::create($page);
    $pdf->setNamedDestination('page_'.$x, $destination{$x});
    $pdf->outlines[0]->childOutlines[] = Zend_Pdf_Outline::create('Page '.$x, $pdf->getNamedDestination('page_'.$x));
    }

    // save documents
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }
    这个也不讲了,看看代码吧。
    $destination{$x} = Zend_Pdf_Destination_Fit::create($page);
    $pdf->setNamedDestination('page_'.$x, $destination{$x});
    $pdf->outlines[0]->childOutlines[] = Zend_Pdf_Outline::create('Page '.$x, $pdf->getNamedDestination('page_'.$x));

    这里可以简化成:
    $pdf->outlines[0]->childOutlines[] = Zend_Pdf_Outline::create('Page '.$x, Zend_Pdf_Destination_Fit::create($page));

    最后讲一下如何设置pdf文件的元信息(meta-data),就是下面的东西:
    12.jpg

    setFont($font, 14);

    // write text to page
    $page->drawText('That which we call a rose,', 72, 720)
    ->drawText('By any other name would smell as sweet.', 72, 620);

    // add page to document
    $pdf->pages[] = $page;

    // set document properties
    $pdf->properties['Author'] = 'William Shakespeare';
    $pdf->properties['Title'] = 'Romeo and Juliet';
    $pdf->properties['Subject'] = 'Act II, Scene II';
    $pdf->properties['Keywords'] = 'shakespeare, romeo, juliet, capulet, montague';
    $pdf->properties['CreationDate'] = "D:201007210634Z00'00'";
    $pdf->properties['ModDate'] = "D:201008150634Z00'00'";

    // save as file
    $pdf->save('example.pdf');
    echo 'SUCCESS: Document saved!';
    } catch (Zend_Pdf_Exception $e) {
    die ('PDF error: ' . $e->getMessage());
    } catch (Exception $e) {
    die ('Application error: ' . $e->getMessage());
    }
    只要设置Zend_Pdf的properties数组里的相关属性即可。

    文章就到这里了。
    其它更多的功能,比如pdf文件与用户交互啦,就靠您自己去测试了。

    Zend_Pdf官方文档:
    http://framework.zend.com/manual/zh/zend.pdf.html

    Thursday, September 16, 2010

    保留小数点后两位的方法

    1. echo round($number,2);

    2. echo sprintf("%.2f", $a);

    3. 直接在数据库中设置数据类型为 decimal(28,2)

    PS: round是对float本身进行加工,如果float本身就符合你的精度要求,就不会有任何改变,所以你用round还是不行
    而sprintf则是对输出就是加工. 已经是字符串了, 想怎么弄就怎么弄

    PS2: 选自《CSDN 社区电子杂志——C/C 杂志》


    在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。这也导致sprintf 比printf 有用得多。

    sprintf 是个变参函数,定义如下:
    int sprintf( char *buffer, const char *format [, argument] ... );
    除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:
    格式化字符串上。



    printf 和sprintf 都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要 的字符串。


    格式化数字字符串
    sprintf 最常见的应用之一莫过于把整数打印到字符串中,所以,spritnf 在大多数场合可以替代
    itoa。


    如:
    //把整数123 打印成一个字符串保存在s 中。
    sprintf(s, "%d", 123); //产生"123"
    可以指定宽度,不足的左边补空格:
    sprintf(s, "��", 123, 4567); //产生:" 123 4567"
    当然也可以左对齐:
    sprintf(s, "%-8d�", 123, 4567); //产生:"123 4567"
    也可以按照16 进制打印:
    sprintf(s, "%8x", 4567); //小写16 进制,宽度占8 个位置,右对齐
    sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8 个位置,左对齐


    这样,一个整数的16 进制字符串就很容易得到,但我们在打印16 进制内容时,通常想要一种左边补0 的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个0 就可以了。
    sprintf(s, "X", 4567); //产生:"000011D7"
    上面以”%d”进行的10 进制打印同样也可以使用这种左边补0 的方式。



    这里要注意一个符号扩展的问题:比如,假如我们想打印短整数(short)-1 的内存16 进制表示形式,在Win32 平台上,一个short 型占2 个字节,所以我们自然希望用4 个16 进制数字来打印它:
    short si = -1;
    sprintf(s, "X", si);
    产 生“FFFFFFFF”,怎么回事?因为spritnf 是个变参函数,除了前面两个参数之外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个“%X”就能得知当初函数调用前参数压栈时被压进来的到底 是个4 字节的整数还是个2 字节的短整数,所以采取了统一4 字节的处理方式,导致参数压栈时做了符号扩展,扩展成了32 位的整数-1,打印时4 个位置不够了,就把32 位整数-1 的8 位16 进制都打印出来了。


    如果你想看si 的本来面目,那么就应该让编译器做0 扩展而不是符号扩展(扩展时二进制左边补0 而不是补符号位):
    sprintf(s, "X", (unsigned short)si);
    就可以了。或者:
    unsigned short si = -1;
    sprintf(s, "X", si);



    sprintf 和printf 还可以按8 进制打印整数字符串,使用”%o”。注意8 进制和16 进制都不会打
    印出负数,都是无符号的,实际上也就是变量的内部编码的直接的16 进制或8 进制表示。


    控制浮点数打印格式
    浮点数的打印和格式控制是sprintf 的又一大常用功能,浮点数使用格式符”%f”控制,默认保
    留小数点后6 位数字,比如:
    sprintf(s, "%f", 3.1415926); //产生"3.141593"
    但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”%m.nf”格式,其中m 表
    示打印的宽度,n 表示小数点后的位数。比如:
    sprintf(s, ".3f", 3.1415626); //产生:" 3.142"
    sprintf(s, "%-10.3f", 3.1415626); //产生:"3.142 "
    sprintf(s, "%.3f", 3.1415626); //不指定总宽度,产生:"3.142"


    注意一个问题,你猜
    int i = 100;
    sprintf(s, "%.2f", i);
    会打出什么东东来?“100.00”?对吗?自己试试就知道了,同时也试试下面这个:
    sprintf(s, "%.2f", (double)i);
    第 一个打出来的肯定不是正确结果,原因跟前面提到的一样,参数压栈时调用者并不知道跟i相对应的格式控制符是个”%f”。而函数执行时函数本身则并不知道当 年被压入栈里的是个整数,于是可怜的保存整数i 的那4 个字节就被不由分说地强行作为浮点数格式来解释了,整个乱套了。不过,如果有人有兴趣使用手工编码一个浮点数,那么倒可以使用这种方法来检验一下你手工编 排的结果是否正确。


    字符/Ascii 码对照
    我们知道,在C/C 语言中,char 也是一种普通的scalable 类型,除了字长之外,它与short,
    int,long 这些类型没有本质区别,只不过被大家习惯用来表示字符和字符串而已。(或许当年该把
    这 个类型叫做“byte”,然后现在就可以根据实际情况,使用byte 或short 来把char 通过typedef 定义出来,这样更合适些)于是,使用”%d”或者”%x”打印一个字符,便能得出它的10 进制或16 进制的ASCII 码;反过来,使用”%c”打印一个整数,便可以看到它所对应的ASCII 字符。以下程序段把所有可见字符的ASCII 码对照表打印到屏幕上(这里采用printf,注意”#”与”%X”合用时自动为16 进制数增加”0X”前缀):
    for(int i = 32; i < 127; i ) {
    printf("[ %c ]: = 0x%#04X\n", i, i, i);
    }



    连接字符串
    sprintf 的格式控制串中既然可以插入各种东西,并最终把它们“连成一串”,自然也就能够连
    接字符串,从而在许多场合可以替代strcat,但sprintf 能够一次连接多个字符串(自然也可以同时
    在它们中间插入别的内容,总之非常灵活)。比如:
    char* who = "I";
    char* whom = "CSDN";
    sprintf(s, "%s love %s.", who, whom); //产生:"I love CSDN. "
    strcat 只能连接字符串(一段以’\0’结尾的字符数组或叫做字符缓冲,null-terminated-string),但有时我们有两段字符缓冲区,他们并不 是以’\0’结尾。比如许多从第三方库函数中返回的字符数组,从硬件或者网络传输中读进来的字符流,它们未必每一段字符序列后面都有个相应的’\0’来结 尾。如果直接连接,不管是sprintf 还是strcat 肯定会导致非法内存操作,而strncat 也至少要求第一个参数是个null-terminated-string,那该怎么办呢?我们自然会想起前面介绍打印整数和浮点数时可以指定宽度,字符串 也一样的。比如:
    char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
    char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};
    如果:
    sprintf(s, "%s%s", a1, a2); //Don't do that!
    十有八九要出问题了。是否可以改成:
    sprintf(s, "%7s%7s", a1, a2);
    也没好到哪儿去,正确的应该是:
    sprintf(s, "%.7s%.7s", a1, a2);//产生:"ABCDEFGHIJKLMN"
    这 可以类比打印浮点数的”%m.nf”,在”%m.ns”中,m 表示占用宽度(字符串长度不足时补空格,超出了则按照实际宽度打印),n 才表示从相应的字符串中最多取用的字符数。通常在打印字符串时m 没什么大用,还是点号后面的n 用的多。自然,也可以前后都只取部分字符:
    sprintf(s, "%.6s%.5s", a1, a2);//产生:"ABCDEFHIJKL"
    在 许多时候,我们或许还希望这些格式控制符中用以指定长度信息的数字是动态的,而不是静态指定的,因为许多时候,程序要到运行时才会清楚到底需要取字符数组 中的几个字符,这种动态的宽度/精度设置功能在sprintf 的实现中也被考虑到了,sprintf 采用”*”来占用一个本来需要一个指定宽度或精度的常数数字的位置,同样,而实际的宽度或精度就可以和其它被打印的变量一样被提供出来,于是,上面的例子 可以变成:
    sprintf(s, "%.*s%.*s", 7, a1, 7, a2);
    或者:
    sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);
    实际上,前面介绍的打印字符、整数、浮点数等都可以动态指定那些常量值,比如:
    sprintf(s, "%-*d", 4, 'A'); //产生"65 "
    sprintf(s, "%#0*X", 8, 128); //产生"0X000080","#"产生0X
    sprintf(s, "%*.*f", 10, 2, 3.1415926); //产生" 3.14"


    打印地址信息
    有时调试程序时,我们可能想查看某些变量或者成员的地址,由于地址或者指针也不过是个32 位的数,你完全可以使用打印无符号整数的”%u”把他们打印出来:
    sprintf(s, "%u", &i);
    不过通常人们还是喜欢使用16 进制而不是10 进制来显示一个地址:
    sprintf(s, "X", &i);
    然而,这些都是间接的方法,对于地址打印,sprintf 提供了专门的”%p”:
    sprintf(s, "%p", &i);
    我觉得它实际上就相当于:
    sprintf(s, "%0*x", 2 * sizeof(void *), &i);
    利用sprintf 的返回值
    较少有人注意printf/sprintf 函数的返回值,但有时它却是有用的,spritnf 返回了本次函数调用
    最终打印到字符缓冲区中的字符数目。也就是说每当一次sprinf 调用结束以后,你无须再调用一次
    strlen 便已经知道了结果字符串的长度。如:
    int len = sprintf(s, "%d", i);
    对于正整数来说,len 便等于整数i 的10 进制位数。
    下面的是个完整的例子,产生10 个[0, 100)之间的随机数,并将他们打印到一个字符数组s 中,
    以逗号分隔开。
    #include
    #include
    #include
    int main() {
    srand(time(0));
    char s[64];
    int offset = 0;
    for(int i = 0; i < 10; i ) {
    offset = sprintf(s offset, "%d,", rand() % 100);
    }
    s[offset - 1] = '\n';//将最后一个逗号换成换行符。
    printf(s);
    return 0;
    }
    设想当你从数据库中取出一条记录,然后希望把他们的各个字段按照某种规则连接成一个字
    符串时,就可以使用这种方法,从理论上讲,他应该比不断的strcat 效率高,因为strcat 每次调用
    都需要先找到最后的那个’\0’的位置,而在上面给出的例子中,我们每次都利用sprintf 返回值把这
    个位置直接记下来了。


    使用sprintf 的常见问题
    sprintf 是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访
    问错误,但好在由sprintf 误用导致的问题虽然严重,却很容易找出,无非就是那么几种情况,通
    常用眼睛再把出错的代码多看几眼就看出来了。


    ?? 缓冲区溢出
    第一个参数的长度太短了,没的说,给个大点的地方吧。当然也可能是后面的参数的问
    题,建议变参对应一定要细心,而打印字符串时,尽量使用”%.ns”的形式指定最大字符数。



    ?? 忘记了第一个参数
    低级得不能再低级问题,用printf 用得太惯了。//偶就常犯。:。(



    ?? 变参对应出问题
    通常是忘记了提供对应某个格式符的变参,导致以后的参数统统错位,检查检查吧。尤
    其是对应”*”的那些参数,都提供了吗?不要把一个整数对应一个”%s”,编译器会觉得你
    欺她太甚了(编译器是obj 和exe 的妈妈,应该是个女的,:P)。


    strftime
    sprnitf 还有个不错的表妹:strftime,专门用于格式化时间字符串的,用法跟她表哥很像,也
    是一大堆格式控制符,只是毕竟小姑娘家心细,她还要调用者指定缓冲区的最大长度,可能是为
    了在出现问题时可以推卸责任吧。这里举个例子:
    time_t t = time(0);
    //产生"YYYY-MM-DD hh:mm:ss"格式的字符串。
    char s[32];
    strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime(&t));
    sprintf 在MFC 中也能找到他的知音:CString::Format,strftime 在MFC 中自然也有她的同道:
    CTime::Format,这一对由于从面向对象哪里得到了赞助,用以写出的代码更觉优雅。

    Tuesday, September 14, 2010

    Zend Framework之使用Zend_Mail实现邮件验证

    ZendChina6月3日:在写这篇文期间就运用了Zend Framework 里面Zend_Mail这一功能..自己也很想用点时间来作一个这方面的总结.现在在开发中又用到了这个功能,所以就在这个时间里写出来,和大家一起分享 一下我的一些经验吧..当然我也是学习前面一些高手的方法..只是不过是自己在这里显示一下。

        Zend Framework 里Zend_Mail这个组件用起来还是很方便的..它提供了通用化的编写与发送文本内容的邮件,当然它也兼容MIME标准的多个多个段的邮件消息的功 能.Zend_Mail里通过默认的Zend_Mail_Transport_SendMail传输或能过 Zend_Mail_Transport_Smtp来发送我们的电子邮件。

        Zend_Mail发送最简单的邮件功能.通过Zend_Mail_Transport_Sendmail发来送.我们只要指定邮件的一个收件人,一个主题,一个邮件内容和一个发件人就可以了.它的代码如下(有注解:):


    <?php
    require_once'Zend/Mail.php';
    $mail=newZend_Mail("UTF-8");//设置邮件编码
    $mail->setBodyText('你的邮件内容放在这里!.')
     
    //发送电子邮件地址以及一些发送人的说明信息
    ->setFrom('fromemail@example.com','发送人的说明信息')
     
    //收信人电子邮件地址以及一些收信人的说明信息
    ->addTo('toemail@example.com','收信人的说明信息')
     
    //电子邮件标题,解决乱码
    ->setSubject("=?UTF-8?B?".base64_encode('电子邮件标题')."?=")
     
    ->send();
    ?> 


        另外一个就是通过一个SMTP发送电子邮件.不过你需要配置你的邮件服务器.这一步大家可以去GOOGLE一下..我就不在这里多说了.我这里是能守 GOOGLE来实现发送电子邮件的..经过我的测试.我的电子邮件到送到自己的Gmail和163(网易)的邮箱都没有问题.乱码问题也解决了..标题长 度限制问题也没有出现..以前是自己参考网上改了Zend_Mail里面的函数..现在用1.6版的Zend Framework好像没有这样的问题..我想是ZF团队改了里面的BUG吧...呵呵..
        下面是自己的实现的代码:

     <?php


    require_onceROOT_PATH .'/Zend/Mail.php';
    require_onceROOT_PATH .'/Zend/Mail/Transport/Smtp.php';
    $mail=newZend_Mail("UTF-8");//设置邮件编码
    $config=array('auth'=>'login',
    'username'=>"kylingood",//电子件用户名
    'password'=>"这里是填写你电子邮件密码",
    'ssl'=>"ssl"
    );
    $transport=newZend_Mail_Transport_Smtp('smtp.gmail.com',$config);
    $mail->setDefaultTransport($transport);
    $mailcontent='欢迎您的到来!<br /> 您的注册名为:
    '.$thisArray['username'].'<br /> 您的密码为:'.$thisArray['userpass'].'
    <br /> 请您点击这里的地址:<a href="#"><font color="red">激活
    </font> </a>您的帐号!
    请尽快删除此邮件,以免别人偷看到您的密码<br /> 如果忘了密码,
    可以到社区写信请管理员重新设定<br />';
     
    $mail->setBodyHtml($mailcontent);//可以发送HTML的邮件.真方便!
    $mail->setFrom('kylingood@gmail.com','kylingood');
    $mail->addTo($email,'kylingood');
    $title=$thisArray['username'].',用户您好,这是网站激活验证邮件!';
    $mail->setSubject("=?UTF-8?B?".base64_encode($title)."?=");
    $mail->send();
    ?> 

         好了,大致用Zend_Mail发送邮件就是这个原理,当然还有更多高级点的用法.比如说邮件发送附件。一次性发送多个电子邮件.还有还有就是使用不同的Transport对象来发送不同的邮件。

    转自:http://www.zendchina.net/?action-viewnews-itemid-1323
    可参考:http://blog.csdn.net/zlb_xidian/archive/2009/08/09/4428756.aspx

    Monday, September 6, 2010

    phpmyadmin如何修改root的 密码

    这个要分两部分:

    第一:打开phpmyadmin会在下方看到提示,root用户没有设置密码,我们先为root帐户设置密码。点击phpmyadmin页面中部的“权限”,可以看到“用户一览”,这时候应该只有一行用户信息,即root localhost这一行,点击这一行最右侧的编辑权限图标,在新页面找到“更改密码”,为root用户设置密码,并点击“执行”。

    第二:打开 config.inc.php  里面找到下面这行
    $cfg['Servers'][$i]['password']       = '';

    引号里就是你想要设置的密码

    PS:WAMPServer这个软件自带的phpmyadmin不能启用用户登入,可以下载最新版PHPMYADMIN替换即可

    Thursday, September 2, 2010

    PHPExcel 循环列

    =============================================================
      
    //Column width
        for($i=ord('A');$i<=ord('Z');$i++){
            $objActSheet->getColumnDimension(chr($i))->setWidth(12);
        }

    ============================================================

    PHP ord() 函数



    定义和用法


    ord() 函数返回字符串第一个字符的 ASCII 值。

    语法


    ord(string) 
    参数 描述
    string 必需。要从中获得 ASCII 值的字符串。

    例子


    <?php echo ord("h"); echo ord("hello"); ?> 

    输出:

    104 104 
    ==========================================================

    PHP chr() 函数



    定义和用法


    chr() 函数从指定的 ASCII 值返回字符。

    语法


    chr(ascii) 
    参数 描述
    ascii 必需。ASCII 值。

    提示和注释


    注释:ascii 参数可以是十进制、八进制或十六进制。通过前置 0 来规定八进制,通过前置 0x 来规定十六进制。

    例子


    <?php echo chr(52); echo chr(052); echo chr(0x52); ?> 

    输出:

    4 * R 

    Monday, August 30, 2010

    Windows+Apache2.2.14+PHP5.3.1+MySQL5.1.41+phpMyAdm

    学习PHP这么久了,昨天发现WAMP已经更新了好几个版本了,我的版本已经很旧了,当然版本并不重要,为
    了复习一下WAMP的配置方法,我在虚拟机中手动和自动配置了下,都是下载最新的推荐版本,原来并没想到
    发到坛子来,所以并没有截图,后来总结到记事本的时候发现还是有蛮多问题的,所以就共享出来,希望对大家
    有所帮助。在做实验的时候,我也参考了坛子里其他的前辈写的教程,在此多谢了。步骤写得比较简略,但重要
    的东西基本都写出来了,有不明白的可以借助搜索引擎,如果我在线,我也会尽力解答的。


    安装过程如下:

    ①手动安装:
    (1)按提示安装Apache 2.2.14,有两种版本(具体有什么区别网上有答案),都行的,安装在C:\WAMP\Apache2.2.14。

    (2)解压php-5.3.1-Win32-VC6-x86.zip(选择VC6,Thread Safe版本)到C:\WAMP\PHP5.3.1中。

    (3)打开httpd.conf,添加以下三行:
           LoadModule php5_module C:/WAMP/PHP5.3.1/php5apache2_2.dll
           PHPIniDir "C:/WAMP/PHP5.3.1"
           AddType application/x-httpd-php .php .phtml
        
           找到
                 <IfModule dir_module>
                        DirectoryIndex index.html
                 </IfModule>

           改为:
                <IfModule dir_module>
                        DirectoryIndex index.html index.php
                </IfModule>


    (4)设置环境变量:C:\WAMP\PHP5.3.1;C:\WAMP\PHP5.3.1\ext;
           还可以把C:\WAMP\Apache2.2.14\bin也添加进去,这样如果Apache出错就可以
           直接在命令控制台中打命令调试。

    (5)修改php.ini:
           找到extension_dir,设置为extension_dir = "C:/WAMP/PHP5.3.1/ext"
           找到以下extension:
           ;extension=php_gd2.dll
           ;extension=php_mbstring.dll
           ;extension=php_mysql.dll
           ;extension=php_mysqli.dll

          去掉之前的分号。这个根据需要去掉前面的分号。

    (6)重启Apache,写个有PHP语句的php网页测试。

    (7)解压mysql-noinstall-5.1.41-win32.zip到C:\WAMP\MySQL5.1.41中

    (8)把my-large.ini改名为my.ini,找到[mysqld]添加如下语句:
          #set default language
          default-character-set=gbk
          #set basedir to your installation path
          basedir=C:/WAMP/MySQL5.1.41
          #set datadir to the location of your data directory
          datadir=C:/WAMP/MySQL5.1.41/data
    (9)先设置环境变量:C:\WAMP\MySQL5.1.41\bin,然后打开命令窗口,输入:
           mysqld --install MySQL --defaults-file=C:\WAMP\MySQL5.1.41\my.ini
           安装完成后在命令窗口输入:mysql -u root
           设置root帐户密码:set password for 'root'@'localhost' = password('123456');
           这样之后就可以使用mysql了,重启Apache,写个php网页测试。

    (10)根据提示安装ZendOptimizer-3.3.0a-Windows-i386.exe。

    (11)解压phpMyAdmin-3.2.4到C:\WAMP\Apache\htdocs\phpMyAdmin中。

    (12)打开文件config.sample.inc.php,寻找到代码行:
            // $cfg['Servers'][$i]['controluser'] = 'pma';
            // $cfg['Servers'][$i]['controlpass'] = 'pmapass';

           改为:
           $cfg['Servers'][$i]['controluser'] = 'root';
            $cfg['Servers'][$i]['controlpass'] = '123456';
           注意:如果需要通过远程服务器调试使用phpMyAdmin,不能让blowfish_secret内容为空。
           可以随便设置一个字符串。

    (13)以config.inc.php保存在同一目录下,现在可以在浏览器中使用phpMyAdmin了。
    至此,手动安装完毕。

    ************************************************************************************
    #####################################################################
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


    ②自动安装:
    (1)按提示安装Apache 2.2.14,有两种版本(具体有什么区别网上有答案),都行的,安装在C:\WAMP\Apache2.2.14。

    (2)运行php-5.3.1-Win32-VC6-x86.msi(选择VC6,Thread Safe版本),安装在C:\WAMP\PHP5.3.1中。

    (3)安装完后在网上找到ntwdblib.dll这个文件,放在C:\WAMP\PHP5.3.1目录中(不推荐这种做法)。
           或者打开php.ini,注释掉下面的一句(就是在前面加个分号,如果已经被注释了那更好):
           extension=php_mssql.dll
           然后重启Apache,这时应该就可以了(如果直接重启Apache,有可能出错)。
           写个php网页测试下。

    (4)运行mysql-5.1.41-win32.msi,安装在C:\WAMP\MySQL5.1.41中。

    (5)重启Apache,新建一个php网页,连接一下MySQL以验证是否安装成功。

    (6)解压phpMyAdmin-3.2.4到C:\WAMP\Apache\htdocs\phpMyAdmin中。

    (7)打开文件config.sample.inc.php,寻找到代码行:
            // $cfg['Servers'][$i]['controluser'] = 'pma';
            // $cfg['Servers'][$i]['controlpass'] = 'pmapass';

           改为:
           $cfg['Servers'][$i]['controluser'] = 'root';
            $cfg['Servers'][$i]['controlpass'] = '123456';
           注意:如果需要通过远程服务器调试使用phpMyAdmin,不能让blowfish_secret内容为空。
           可以随便设置一个字符串,最好是设置一个字符串。


    (8)以config.inc.php保存在同一目录下,现在可以在浏览器中使用phpMyAdmin了。
           至此,自动安装完毕。

    转自:http://bbs.phpchina.com/viewthread.php?tid=170073&highlight=phpmyadmin