页面载入中...
首页 » PHP

php经验和sql经验[转载]

 1 在SQL语句中可通过添加限制条件:left(text,20)只取text文本的前20个字;

  2 可以用limit fromRecord, RecordNum 来作为分页使用,比如limit 0,30表示从第一个记录开始遍历30个纪录;

  3 两个表的连接可以是:table1 join table2 using x(x为两个表的公共字段),或者是table1 join table2 on table1.x = table2.x

  4 php获取querystring可以用$page = $_GET['page'];

  或者

  $page = $_REQUEST['page'];

  其中Request可取得post,get,QueryString等字符;

  在这之前 我看到了一个较笨的办法:

  parse_str($_SERVER['QUERY_STRING'],$output); // 先将查询字符串存到一个数组$output中

  $page = $output['page']; //然后根据变量名索引

  5 php中日期函数的比较实际上就是字符串的比较;

  6 mysql中date类型的数据可以是:2000-02-03,2002.02.03,2002.2.3,02.02.03,02.2.3,就是说必须有月和日,而且必须以’-'或’.'分隔开来。

  7 data()来获取时间会有时区的问题,我发现时间都少了8个小时,是因为php.ini里面默认配置是GTM美国时区;

  解决办法:可以修改php.ini:

  [Date]

  ; Defines the default timezone used by the date functions

  date.timezone = “Asia/Shanghai”

  或者在使用date()函数是加上date_Default_TimeZone_set(“PRC”);

  8 一段时间,调试时在body处总是说我缺少”)”,费了半天是intval($_POST['consumeType'])的问题,在数据库中该字段是varchar(50),在zengsong表中我没用intval函数,是因为它的ID就是1,2…整数跟char型的可以互相转换,但在另外两个表中是A5A,SP07-01之类的,但它怎么转换成int型了呢?

  让我们来看看intval函数的声明:

  intval函数用来获取变量的整数值:int intval ( mixed var [, int base] )

  通过使用特定的进制转换(默认是十进制),返回变量 var 的 integer 数值。

  var 可以是任何标量类型。intval() 不能用于 array 或 object。

  9 另外一个莫名的问题,以用户名1登陆就可以,换个’bo’登陆,系统就在处出错:说我运行时间错误:缺少”)”,nnd。检查了一下,原来是sql语句中的变量类型跟数据库中的不一致,

  10 php中当从浮点数转换成整数时,数字将被取整(丢弃小数位)。

  11 在mysql插入语句中,如果是自增字段要用(NULL)来代替。

  12 php的中文乱码???问题解决:

  在mysql_connect后加入mysql_query(“set names ‘gb2312′”);

  或者全用utf8编码,就不用加入上述语句了。

  还有函数iconv(“GBK”,”UTF8″,”字符串”);可实现各种字符编码的转换。

5 个 PHP 编程的好习惯

作者:Nathan A. Good
原文链接:http://www.ibm.com/developerworks/opensource/library/os-php-5goodhabits/index.html?ca=dgr-jw64os-php-5goodhabits&S_TACT=105AGY46&S_CMP=GRsitejw64

有些人问,优秀程序员和大牛有什么区别,大概有10到20种吧。因为大牛有很好的编程习惯和丰富的经验,所以他们非常的高效。如果不好的编程习惯出现在你的代码里,你的代码效率就会降低。本文阐述一些好的编程习惯,他们可以让你成为更好的程序员。

这些习惯能让你的代码在高效运行的同时提高可维护性。你写代码的时候,可能大部分时间都浪费在维护上了,程序的维护代价很高。培养良好的编程习惯,如模块化设计,可以让你的代码可读性更好,从而容易维护。

代码中的问题往往伴随着不良的编程习惯,而且后者会导致代码不好修改并可能出现新的缺陷。下面有五个好的编程习惯,将帮你避免这些陷阱:
使用友好的命名方式。
使用更精悍短小的代码。
注释你的代码。
编写异常处理。
永远,永远不要复制粘贴.(玉米:我深深的同意这一点)

下面的章节将解释这些习惯。
使用友好的命名方式

良好的命名方式是最重要的编程习惯,因为好的命名会让代码易懂,好懂。代码的可读性决定它的可维护性。即使你在代码没有写注释,如果它可读性好的话,它也修改起来也会简单。你应该在练习开时就使用良好的命名方式,让你的代码像一本书一样。

例1 包含一个过短的变量名,写出这样的代码非常不好弄懂,而且函数名也没有清晰的描述出这个方法是做什么的。函数名表示了函数的功能,如果它却是做别的用途的,那就会误导别人。

Listing 1. Bad: Ambiguous or meaningless names1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 <?php
function getNBDay($d)
{
switch($d) {
case 5:
case 6:
case 7:
return 1;
default:
return ($d + 1);
}
}

$day = 5;

$nextDay = getNBDay($day);

echo (“Next day is: ” . $nextDay . “n”);
?>


例2 则给出了使用良好命名方式的代码。重新命名函数是为了更好的反映它们的功能。变量也重新命名为描述性的。只有一个在循环中的$i还使用短的变量名。尽管有些人不同意,短变量名在循环中是请允许的–甚至更好些,因为它们清晰的起到了指针的功能。

Listing 2. Good: Reflective yet concise names1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 <?php
define (‘MONDAY’, 1);
define (‘TUESDAY’, 2);
define (‘WEDNESDAY’, 3);
define (‘THURSDAY’, 4);
define (‘FRIDAY’, 5);
define (‘SATURDAY’, 6);
define (‘SUNDAY’, 7);

/*
*
* @param $dayOfWeek
* @return int Day of week, with 1 being Monday and so on.
*/
function findNextBusinessDay($dayOfWeek)
{
$nextBusinessDay = $dayOfWeek;

switch($dayOfWeek) {
case FRIDAY:
case SATURDAY:
case SUNDAY:
$nextBusinessDay = MONDAY;
break;
default:
$nextBusinessDay += 1;
break;
}

return $nextBusinessDay;
}

$day = FRIDAY;

$nextBusDay = findNextBusinessDay($day);

echo (“Next day is:” . $nextBusDay . “n”);

?>


我鼓励你在函数中分隔长的条件给函数命名,以便于描述这个条件。(玉米:这句话啥意思?5555)这个技巧会让你的代码容易阅读和扩展,因此它可以被抽象复用。如果条件发生了改变,这样也会很容易更新函数 .由于方法有一个见名知义的名字,化码就不会失去它本来的意思或者变得难以理解。
使用更少的代码

编写代码、解决问题是一种容易的事情。当你解决一个正在发生的问题,编呀编,写呀写,你的方法越来越长。只要你回头使用更少的代码来重构,就是过了很久也没什么问题。

重构是个好主意,但你应该养成第一次就写出更短小精悍代码的习惯。在一个窗口上(玉米:不用翻页)就能看全的短小函数更容易理解。 要是一个函数长出了窗口,就很难理解了,因为你不能快速的从头到脚的浏览整个代码。

当构思一个方法的时候,你还应该养成一个让它们只做一件事情的习惯。以下因素写代码时应常注意。第一,只做一件事情的函数更易于复用。第二,这样的函数测试更方便。第三,这样的函数好读易懂方便改–如果必要的话–让它们尽可能的简单吧。
坏习惯:过长的函数(很多时候)

例三是过长函数的表现。它不知道自己要做什么。它做太多的事情,所以没有集成化。它更难以理解,不好Debug和测试。它遍历文件建立列表,它给对象赋值,它做一些计算,……它耕田,它浇水,甚至做更多事情。(^_^)

例三. 坏习惯:过长函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 <?php
function writeRssFeed($user)
{
// Get the DB connection information


// look up the user’s preferences…
$link = mysql_connect(‘mysql_host’, ‘mysql_user’, ‘mysql_password’)
OR die(mysql_error());

// Query
$perfsQuery = sprintf(“SELECT max_stories FROM user_perfs WHERE user= ‘%s’”,
mysql_real_escape_string($user));

$result = mysql_query($query, $link);

$max_stories = 25; // default it to 25;

if ($row = mysql_fetch_assoc($result)) {
$max_stories = $row['max_stories'];
}

// go get my data
$perfsQuery = sprintf(“SELECT * FROM stories WHERE post_date = ‘%s’”,
mysql_real_escape_string());

$result = mysql_query($query, $link);


$feed = “<rss version=”2.0″>” .
“<channel>” .
“<title>My Great Feed</title>” .
“<link>http://www.example.com/feed.xml</link>” .
“<description>The best feed in the world</description>” .
“<language>en-us</language>” .
“<pubDate>Tue, 20 Oct 2008 10:00:00 GMT</pubDate>” .
“<lastBuildDate>Tue, 20 Oct 2008 10:00:00 GMT</lastBuildDate>” .
“<docs>http://www.example.com/rss</docs>” .
“<generator>MyFeed Generator</generator>” .
“<managingEditor>editor@example.com</managingEditor>” .
“<webMaster>webmaster@example.com</webMaster>” .
“<ttl>5</ttl>”;

// build the feed…
while ($row = mysql_fetch_assoc($result)) {
$title = $row['title'];
$link = $row['link'];
$description = $row['description'];
$date = $row['date'];
$guid = $row['guid'];

$feed .= “<item>”;
$feed .= “<title>” . $title . “</title>”;
$feed .= “<link>” . $link . “</link>”;
$feed .= “<description> ” . $description . “</description>”;
$feed .= “<pubDate>” . $date . “</pubDate>”;
$feed .= “<guid>” . $guid . “</guid>”;
$feed .= “</item>”;
}

$feed .= “</rss”;

// write the feed out to the server…
echo($feed);

}

?>


要是你再加更多东西到这个函数里,它会很快变得难以维护。
好习惯:可管理,集成化的函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 <?php

function createRssHeader()
{
return “<rss version=”2.0″>” .
“<channel>” .
“<title>My Great Feed</title>” .
“<link>http://www.example.com/feed.xml</link>” .
“<description>The best feed in the world</description>” .
“<language>en-us</language>” .
“<pubDate>Tue, 20 Oct 2008 10:00:00 GMT</pubDate>” .
“<lastBuildDate>Tue, 20 Oct 2008 10:00:00 GMT</lastBuildDate>” .
“<docs>http://www.example.com/rss</docs>” .
“<generator>MyFeed Generator</generator>” .
“<managingEditor>editor@example.com</managingEditor>” .
“<webMaster>webmaster@example.com</webMaster>” .
“<ttl>5</ttl>”;
}

function createRssFooter()
{
return “</channel></rss>”;
}

function createRssItem($title, $link, $desc, $date, $guid)
{
$item .= “<item>”;
$item .= “<title>” . $title . “</title>”;
$item .= “<link>” . $link . “</link>”;
$item .= “<description> ” . $description . “</description>”;
$item .= “<pubDate>” . $date . “</pubDate>”;
$item .= “<guid>” . $guid . “</guid>”;
$item .= “</item>”;
return $item;
}

function getUserMaxStories($db_link, $default)
{
$perfsQuery = sprintf(“SELECT max_stories FROM user_perfs WHERE user= ‘%s’”,
mysql_real_escape_string($user));

$result = mysql_query($perfsQuery, $db_link);

$max_stories = $default;

if ($row = mysql_fetch_assoc($result)) {
$max_stories = $row['max_stories'];
}

return $max_stories;
}

function writeRssFeed($user)
{
// Get the DB connection information
$settings = parse_ini_file(“rss_server.ini”);

// look up the user’s preferences…
$link = mysql_connect($settings['db_host'], $settings['user'],
$settings['password']) OR die(mysql_error());

$max_stories = getUserMaxStories($link, 25);

// go get my data
$newsQuery = sprintf(“SELECT * FROM stories WHERE post_date = ‘%s’”,
mysql_real_escape_string(time()));

$result = mysql_query($newsQuery, $link);

$feed = createRssHeader();

$i = 0;
// build the feed…
while ($row = mysql_fetch_assoc($result)) {
if ($i < $max_stories) {
$title = $row['title'];
$link = $row['link'];
$description = $row['description'];
$date = $row['date'];
$guid = $row['guid'];

$feed .= createRssItem($title, $link, $description, $date, $guid);

$i++;
} else {
break;
}
}

mysql_close($link);

$feed .= createRssFooter();

// write the feed out to the server…
echo($feed);
}
?>


把长函数分割会导致效率降低,所以要注意,这个好习惯不要使用过度。这样做可能也会引起阅读性差,跟原来人家是一个整体时没什么区别。
注释代码

注释你的代码有时就像你刚着手写代码一样困难。明确注释内容很棘手,因为他要写出代码要做什么。注释变量是一个好主意。在函数头部注释可能不太明显时,就可以告诉阅读者函数要什么参数,有什么返回以及主要的意图。

通常大家会注释代码是做什么的,但这并不必要。如果代码让人困惑以至于你不得不写注释说它是做什么的,这就提示你应该重写它,使它更好懂。命名良好、更加短小、组织合理的代码习惯会让你的代码用不着注释就拥有很高的可读性。
坏习惯:压根没有或者叽叽歪歪的函数注释 (^_^)

例5 的注释只给出了代码在做什么–它的通过循环的遍历、加了个数。但是丢了为什么这么做和要做什么。 这会让别人难以不影响原代码的情形下安全修改的做出修改。

例5 :压根没胡或者叽叽歪歪的函数注释1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 <?php

class ResultMessage
{
private $severity;
private $message;

public function __construct($sev, $msg)
{
$this->severity = $sev;
$this->message = $msg;
}

public function getSeverity()
{
return $this->severity;
}

public function setSeverity($severity)
{
$this->severity = $severity;
}

public function getMessage()
{
return $this->message;
}

public function setMessage($msg)
{
$this->message = $msg;
}
}

function cntMsgs($messages)
{
$n = 0;
/* iterate through the messages… */
foreach($messages as $m) {
if ($m->getSeverity() == ‘Error’) {
$n++; // add one to the result;
}
}
return $n;
}

$messages = array(new ResultMessage(“Error”, “This is an error!”),
new ResultMessage(“Warning”, “This is a warning!”),
new ResultMessage(“Error”, “This is another error!”));

$errs = cntMsgs($messages);

echo(“There are ” . $errs . ” errors in the result.n”);

?>

好习惯: 注释函数和类

例6 里的注释标明了类和函数的意图。注释表明方法做了什么和为什么做,这会对将来了解代码的意图很有帮助。环境的变化会需要你进行代码修改,这就会让很容易的知道开始时你代码是做什么的。

例6.好习惯:注释函数和类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 <?php
/**
* The ResultMessage class holds a message that can be returned
* as a result of a process. The message has a severity and
* message.
*
* @author nagood
*
*/
class ResultMessage
{
private $severity;
private $message;

/**
* Constructor for the ResultMessage that allows you to assign
* severity and message.
* @param $sev See {@link getSeverity()}
* @param $msg
* @return unknown_type
*/
public function __construct($sev, $msg)
{
$this->severity = $sev;
$this->message = $msg;
}

/**
* Returns the severity of the message. Should be one
* “Information”, “Warning”, or “Error”.
* @return string Message severity
*/
public function getSeverity()
{
return $this->severity;
}

/**
* Sets the severity of the message
* @param $severity
* @return void
*/
public function setSeverity($severity)
{
$this->severity = $severity;
}

public function getMessage()
{
return $this->message;
}

public function setMessage($msg)
{
$this->message = $msg;
}
}

/*
* Counts the messages with the given severity in the array
* of messages.
*
* @param $messages An array of ResultMessage
* @return int Count of messages with a severity of “Error”
*/
function countErrors($messages)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == “Error”) {
$matchingCount++;
}
}
return $matchingCount;
}

$messages = array(new ResultMessage(“Error”, “This is an error!”),
new ResultMessage(“Warning”, “This is a warning!”),
new ResultMessage(“Error”, “This is another error!”));

$errs = countErrors($messages);

echo(“There are ” . $errs . ” errors in the result.n”);

?>

异常处理

写健壮应用时经常会提到的异常处理,一般遵循着80/20原则: 80%的代码用于处理异常或者验证,20%的代码没什么实际的用途。原始的代码通常都是在乐观的环境下编写的。这意味着代码可以在数据正常、一切理解的基础环境中工作的很好。但是这种代码在其生命周期内是脆弱的。在极端的情形中,你得花更多的时间来未很可能永远不会发生的状况编写相应代码。

这个习惯就是要你处理全部的出错情况,而且如果要是不这么做,你的代码永远也完不成。
坏习惯:不处理任何异常1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 <?php

// Get the actual name of the
function convertDayOfWeekToName($day)
{
$dayNames = array(
“Sunday”,
“Monday”,
“Tuesday”,
“Wednesday”,
“Thursday”,
“Friday”,
“Saturday”);
return $dayNames[$day];
}

echo(“The name of the 0 day is: ” . convertDayOfWeekToName(0) . “n”);
echo(“The name of the 10 day is: ” . convertDayOfWeekToName(10) . “n”);
echo(“The name of the ‘orange’ day is: ” . convertDayOfWeekToName(‘orange’) . “n”);

?>

好习惯: 防守型编程

例8 表明处理并抛出异常是一件很有意义的事情。不只是额外的异常处理可以让代码健壮,但是这有助于提高代码的可读性。这种异常处理为原作者查看何时编写提供了一个很好的说明。

例8.好习惯:防守型编程1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 <?php

/**
* This is the exception thrown if the day of the week is invalid.
* @author nagood
*
*/
class InvalidDayOfWeekException extends Exception { }

class InvalidDayFormatException extends Exception { }

/**
* Gets the name of the day given the day in the week. Will
* return an error if the value supplied is out of range.
*
* @param $day
* @return unknown_type
*/
function convertDayOfWeekToName($day)
{
if (! is_numeric($day)) {
throw new InvalidDayFormatException(‘The value ” . $day . ” is an ‘ .
‘invalid format for a day of week.’);
}

if (($day > 6) || ($day < 0)) {
throw new InvalidDayOfWeekException(‘The day number ” . $day . ” is an ‘ .
‘invalid day of the week. Expecting 0-6.’);
}

$dayNames = array(
“Sunday”,
“Monday”,
“Tuesday”,
“Wednesday”,
“Thursday”,
“Friday”,
“Saturday”);
return $dayNames[$day];
}

echo(“The name of the 0 day is: ” . convertDayOfWeekToName(0) . “n”);

try {
echo(“The name of the 10 day is: ” . convertDayOfWeekToName(10) . “n”);
} catch (InvalidDayOfWeekException $e) {
echo (“Encountered error while trying to convert value: ” . $e->getMessage() . “n”);
}

try {
echo(“The name of the ‘orange’ day is: ” . convertDayOfWeekToName(‘orange’) . “n”);
} catch (InvalidDayFormatException $e) {
echo (“Encountered error while trying to convert value: ” . $e->getMessage() . “n”);
}

?>


通过检验参数的全法性–这有助于他人使用你需要正确参数的函数–你应该检验它们并抛出异常的大意:
尽量抛出接近错误的异常.
处理每个特殊的异常.
永远,永远不要复制粘贴

把代码复制到你的编辑里的能力是一把双刃剑。一方面,它避免了你参照一些示例后重新再打一遍时出现的错误;另一方面,它让书写相似代码太简单了。

你要避免在你的程序应用中复制粘贴代码。当你发现自己在这样做时,停下来并问自己可不可以把复制的部分重复使用。把相同的代码放在同一个地方可以让你以后修改时更加的轻松,因为要改变都在一起。
坏习惯:相似的代码块

例9 表现了除了一些值所在位置之外很相近的几个方法。有些工具可以检验你的代码中复制粘贴的部分(去看看Resources)。

例9.相似的代码块1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 <?php
/**
* Counts the number of messages found in the array of
* ResultMessage with the getSeverity() value of “Error”
*
* @param $messages An array of ResultMessage
* @return unknown_type
*/
function countErrors($messages)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == “Error”) {
$matchingCount++;
}
}
return $matchingCount;
}

/**
* Counts the number of messages found in the array of
* ResultMessage with the getSeverity() value of “Warning”
*
* @param $messages An array of ResultMessage
* @return unknown_type
*/
function countWarnings($messages)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == “Warning”) {
$matchingCount++;
}
}
return $matchingCount;
}

/**
* Counts the number of messages found in the array of
* ResultMessage with the getSeverity() value of “Information”
*
* @param $messages An array of ResultMessage
* @return unknown_type
*/
function countInformation($messages)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == “Information”) {
$matchingCount++;
}
}
return $matchingCount;
}

$messages = array(new ResultMessage(“Error”, “This is an error!”),
new ResultMessage(“Warning”, “This is a warning!”),
new ResultMessage(“Error”, “This is another error!”));

$errs = countErrors($messages);

echo(“There are ” . $errs . ” errors in the result.n”);
?>

好习惯:可复用的带参函数

例10 展示了把要复制的代码入到一个方法中的代码修改。另一个修改的方法则把工作代理给了一个新的方法 。编写一个通用的方法要花一些时间来设计,当然这会让你停下来思考,而不是用复制粘贴的组合快捷键。但是这样做会在以后修改时省回第一次多花的时间。

例10.好习惯 :可利用的带参函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 <?php
/*
* Counts the messages with the given severity in the array
* of messages.
*
* @param $messages An array of ResultMessage
* @return int Count of messages matching $withSeverity
*/
function countMessages($messages, $withSeverity)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == $withSeverity) {
$matchingCount++;
}
}
return $matchingCount;
}

/**
* Counts the number of messages found in the array of
* ResultMessage with the getSeverity() value of “Error”
*
* @param $messages An array of ResultMessage
* @return unknown_type
*/
function countErrors($messages)
{
return countMessages($messages, “Errors”);
}

/**
* Counts the number of messages found in the array of
* ResultMessage with the getSeverity() value of “Warning”
*
* @param $messages An array of ResultMessage
* @return unknown_type
*/
function countWarnings($messages)
{
return countMessages($messages, “Warning”);
}

/**
* Counts the number of messages found in the array of
* ResultMessage with the getSeverity() value of “Warning”
*
* @param $messages An array of ResultMessage
* @return unknown_type
*/
function countInformation($messages)
{
return countMessages($messages, “Information”);
}

$messages = array(new ResultMessage(“Error”, “This is an error!”),
new ResultMessage(“Warning”, “This is a warning!”),
new ResultMessage(“Error”, “This is another error!”));

$errs = countErrors($messages);

echo(“There are ” . $errs . ” errors in the result.n”);

?>

结论

如果当你开发 PHP 的时候养成了本文中提到的好习惯,你写的代码将会好读、好懂、好维护。编写可维护代码的方式将让你的代码可以高度排错,并告别低级错误。

使用良好命名并用短代码块来组强你的代码会让你的代码简单明了。注明你代码的目的会让它的主旨明确易于理解。异常处理让你的代码健壮。最后,摒弃复制粘贴的恶习让你的代码整洁。

——————

玉米寄语:最后的这个复制粘贴的建议让我一身冷汗,想想其实有很多代码都是重复的工作,有时只是为了”快”,而把相似的代码又”复制”了一遍,虽然我没有使用ctrl+cv 但是也是写了很多类似的代码,看来,review的事儿可以在世界和平的事儿之前考虑了。

[翻译:玉米疯收,来源地址]

– EOF –

风雨20年:我所积累的20条编程经验[转载]

编者按:原文作者乔纳森·丹尼可(Jonathan Danylko)是一位自由职业的web架构师和程序员,编程经验已超过20年,涉足领域有电子商务、生物技术、房地产、医疗、保险和公用事业。正如乔纳 森在文中所言,本文适合刚毕业的大学生和刚入门的程序员。如果你已是高级开发人员,或许你在本文中看到自己的身影。

从11岁时,我就一直在编程,并且一直都很喜欢技术和编程。这些年来,我积累了一些艰难又容易的经验。作为一名程序员,你或许还没这些经验,但我会把它们献给那些想从中学到更多的朋友。

我会持续更新这些经验,我可能还会有更多的感想,但就我这20年来看,我想下面这个列表中基本不需要增添额外的东西了。下面就是我至今最难忘的经验。

1. 估算解决问题所需要的时间。不要怕,承认吧!我曾见过一些程序员为了解决一个特殊问题而坐在显示器前面8小时。为自己定一个时间限制吧,1小时、30分钟或甚至15分钟。如果在这期间你不能解决问题,那就去寻求帮助,或到网上找答案,而不是尝试去做”超级堆码员”。

2. 编程语言是一种语言,只是一种语言。随着时光推移,只要你理解了一种语言的原理,你会发现各种语言之间的相似之处 。你所选择的语言,你应该觉得”舒服”,并且能够写出有效(而且简洁)的代码。最重要的,让语言去适应项目,反之亦然。

3. 不要过于注重程序的”设计模式”。 有时候,写一个简单的算法,要比引入某种模式更容易。在多数情况下,程序代码应是简单易懂,甚至清洁工也能看懂。

4. 经常备份代码。在我年轻时,我就有过因硬盘故障而丢了大量代码的经历,这经历很恐怖的。只要你一次没有备份,就应当像有着严格的期限,客户明天就需要。此时就该源码/版本控制软件大显身手了。

5. 承认自己并不是最顶尖的程序员 – 知不足。我常想,我对编程了解已足够多,但是总有其他人比你优秀。正所谓,”一山总比一山高”。所以,向他们看齐吧!

6、学习再学习。正如第5点所说,我经常会在手里拿一本计算机或编程相关的杂志或书(不信,可以问我的朋友)。诚然,总有很多你不知道的技术,你可以从中学习以保持不落后。如果你有一种灵巧的方式来获取你需要的新技术,那你每天都应该坚持学习。

7. 永恒的变化。你对待技术/编程知识,就应像你对待股票一样:多样化。不要在某一特定技 术上自我感觉良好。如果那种技术或语言已经没有足够支持,那你还不如现在就开始更新你的简历,并启动培训新计划。我能保持前行的主要原则是什么呢?至少了 解两到三种语言,所以,如果某种语言过时了,你在学习新技术的时候还可以依靠另一种语言。

8. 提携新人。协助并且培养初级/入门的开发人员学习优秀的编程方法和技巧。也许你还不知道,在帮助他们向更高一层前进时,你自己也在向更高一层提升,你会更加自信。

9. 简化算法。代码如恶魔,在你完成编码后,应回头并且优化它。从长远来看,这里或那里一些的改进,会让后来的支持人员更加轻松。

10. 编写文档。无论是Web服务的API,还是一个简单的类,你尽量编写相应文档。我曾经引以为豪的代码注释,因过度 注释而有人指责。给三行代码加一行注释,只需要你几秒时间。如果那是一个比较难以理解的技术,千万别担心过多注释。如果你能很好做好自己的工作,大多数架 构师、后备程序员、支持组都会感激你。

11. 测试、测试再测试。我是一名黑盒测试粉丝。当你完成编码后,你”被认可”的时候就开始了。如果你们公司有QA部门,如果你的代码中有错误,那你得到的评论,会比项目经理还多。如果你不彻底测试自己的代码,那恐怕你开发的就不只是代码,可能还会声名狼藉。

12. 庆祝每一次成功。我见过很多程序员在解决编程技术难题后,会和同伴握手、击掌或甚至手舞足蹈。每个人在生命中都会碰到”顿悟”。如果一个程序员高兴地跑来叫你去看他的非凡代码,也许你已经看过这样的代码100遍了,但你也应该为了这个家伙而庆祝第101次。

13. 经常检查代码。 在公司,你的代码要经常检查(包括自查和其他同事检查)。不要把别人的检查,看成是对代码风格的苛求。应该把它们看作是有建设性的批评。对个人来说,经常检查你的代码并且自问,”我怎样才能写得更好呢?” 这会让你加速你的成长,让你成为一个更优秀的程序员。

14. 回顾你的代码。在看到自己以前的代码时,通常会有两种方式:”难以至信,这代码是我写的”和”难以至信,这代码是 我写的”。第一种往往是厌恶的语气,并在想如何改进它。你也许会惊叹,旧代码也能复活成为一种更好的程序,甚至是一个完整的产品。第二种通常带着惊奇和成 就感。开发人员应该一到两个自己完成的项目成果,能让众人不禁而立并注目而观的项目。同样,基于你优越的编程能力,你可以把过去的程序或项目拿出来,把它 们更新为更加优秀的产品或想法。

15. 幽默是不可缺的。在我20年的开发生涯中,我还没有碰到哪位程序员是没有幽默感的。实际上,干我们这行,幽默是一项必备品。

16. 谨防那些无所不知的程序员,不愿分享的程序员,还有经验不足的程序员。当你遇到这几种程序员时,你自己要谦虚。无所不知的程序员,更想当一个英雄而不是团队成员;保守的程序员则是在编写着他们独享的代码;而经验不足的程序员则会每十分钟就来问你一下,当代码完成后,代码已经是你的,而不是他们。

17. 任何项目都不会那么简单。朋友、家人和同事曾请求我仓促做一些事情,仓促做一个程序或者网站。对于这样的事,应该 从双方做计划,才能做出令两方都会满意的东西。如果某人起初只是需要一个使用Microsoft Access的、只有有3个页面的网站,但来就很可能变成一个有15个页面的网站,并使用SQL Server,有一个论坛,还有一个定制的CMS(内容管理系统)。

18. 任何时候不要想当然。假如你承接一个简单的项目,你可能会认为某个部分可以轻松完成。千万别这样想!除非你有一个类、组件、或者一段已经写好的代码,并且在现有的项目已经测试通过。不要认为这将是很容易的。

19. 没有已经完成的软件。曾经有一位程序员告诉我,没有软件是已经完成的,它只是”暂时完成了”。这是明智的忠告。如果客户还在使用你写的程序,并经受了时间的考验。如果有机会,你仍在更新它,这并不是什么坏事,这让你不断地前行。

20. 耐心是一种美德。当客户、朋友或家庭成员用电脑的时候,他们也许会受挫,进而想砸电脑,或气冲冲地离开。我一直在 告诉他们,”是你掌控电脑,不是电脑掌控你。”对于用作编程的电脑,你要有一定的耐心。一旦程序员知道问题所在后,他们就会站在电脑的角度看问题,并且说 “哦,这就是为什么它是这样做。”

编者后话

对本文深有感触!虽然本文没有华丽的辞藻,其中朴实的道理,其实并非只适用程序员,同样可以扩展到其他行业。记得以前练字时,总感觉当时写得很好,但后来回头再看时,也会想”这居然是我写的字!”

在阅读本文的朋友,不知你是否也有看到了自己的身影呢?欢迎你在微博或评论中和大家一起分享感触。

本文出处:伯乐在线 – 职场博客

本文链接:http://www.jobbole.com/entry.php/322

Via:Jonathan Danylko 编译:伯乐在线 敏捷翻译组 – @关关

如意盒de免费PHP空间,免费分享优质国外空间

如意盒de免费PHP空间,免费分享优质国外空间
# 无需备案+超强中文控制面板cpanel+域名邮箱+多个域名绑定+不限容量的mysql数据库

# 可自行绑定 2个一级域名, N个二级域名,随意开通 N 个共享磁盘空间容量的企业邮箱(如:admin@你的域名)
# ? M 的空间,每个网站月流量限制 ? G(?=随机)
# 可建立 N 个MYSQL数据库(共享磁盘容量),支持PhpMyAdmin在线管理
# 支持文件
在线压缩、解压缩,支持web在线文件管理
# N 个FTP账号,并支持SSH
# 支持
SSL, FTP, Stats ,手机wap浏览,支持泛域名解析,.htaccess
#mod_rewrite组件支持,可直接设置各类程序的伪静态

# 支持CGI,Perl,PHP,MySQL,不支持ASP
#空间支持国内、国外各种PHP程序,如discuz、phpwind、DEDECMS、PHPCMS、Supesite、帝国cms、ecshop、shopex、wordpress、zen-cart、Joomla、淘宝客站,168整站系统等(不支持ASP和ASP.NET)

术语解析:cpanel–虚拟主机控制系统。在cPanel主机上,您可以自如控制一切,无需联系服务商开通或调整任何功能,所有你想得到的功能都可以在控制界面自助完成。在cPanel做不到的功能,99%的可能性是根本不适合在虚拟主机环境(来自百度百科)。

本空间不允许放置仿牌外贸站,下载站、发布垃圾邮件、带有涉及版权的内容、在服务器上大量采集站、电影、游戏、私服、成人站点、国内禁止的某类图片站、擦边站、美女聊天室,并且本站禁止存放任何与中国和美国法律相抵触的内容

PHP探针(http://ruyice.com/tanzhen.php
PHP详细信息(http://ruyice.com/phpinfo.php
支持手机wap访问,测试地址(http://ruyice.com/wap.php
cpanel使用教程(http://ruyice.com/cp
后台管理登陆(http://ruyice.com/cpanel
企业(域名)邮箱登陆(http://ruyice.com/webmail

用PHP的Socket建立自己的聊天室服务器

<?PHP
/**
* patServer
* PHP socket server base class
* Events that can be handled:
* * onStart
* * onConnect
* * onConnectionRefused
* * onClose
* * onShutdown
* * onReceiveData
*
* @version 1.1
* @author Stephan Schmidt < schst@php-tools.de >
* @package patServer
*/
class patServer{
/**
* information about the project
* @var array $systemVars
*/
var $systemVars = array(

“appName” => “patServer”,
“appVersion” => “1.1″,
“author” => array(“Stephan Schmidt < schst@php-tools.de >”, )
);

/**
* port to listen
* @var integer $port
*/
var $port = 10000;

/**
* domain to bind to
* @var string $domain
*/
var $domain = “localhost”;

/**
* maximum amount of clients
* @var integer $maxClients
*/
var $maxClients = -1;

/**
* buffer size for socket_read
* @var integer $readBufferSize
*/
var $readBufferSize = 128;

/**
* end character for socket_read
* @var integer $readEndCharacter
*/
var $readEndCharacter = “\n”;

/**
* maximum of backlog in queue
* @var integer $maxQueue
*/
var $maxQueue = 500;

/**
* debug mode
* @var boolean $debug
*/
var $debug = true;

/**
* debug mode
* @var string $debugMode
*/
var $debugMode = “text”;

/**
* debug destination (filename or stdout)
* @var string $debugDest
*/
var $debugDest = “stdout”;

/**
* empty array, used for socket_select
* @var array $null
*/
var $null = array();

/**
* all file descriptors are stored here
* @var array $clientFD
*/
var $clientFD = array();

/**
* needed to store client information
* @var array $clientInfo
*/
var $clientInfo = array();

/**
* needed to store server information
* @var array $serverInfo
*/
var $serverInfo = array();

/**
* amount of clients
* @var integer $clients
*/
var $clients = 0;

/**
* create a new socket server
*
* @access public
* @param string $domain domain to bind to
* @param integer $port port to listen to
*/
function patServer( $domain = “localhost”, $port = 10000 ){
$this->domain = $domain;
$this->port = $port;

$this->serverInfo["domain"] = $domain;
$this->serverInfo["port"] = $port;
$this->serverInfo["servername"] = $this->systemVars["appName"];
$this->serverInfo["serverversion"] = $this->systemVars["appVersion"];

set_time_limit( 0 );
}

/**
* set maximum amount of simultaneous connections
*
* @access public
* @param int $maxClients
*/
function setMaxClients( $maxClients ){
$this->maxClients = $maxClients;
}

/**
* set debug mode
*
* @access public
* @param mixed $debug [text|htmlfalse]
* @param string $dest destination of debug message (stdout to output or filename if log should be written)
*/
function setDebugMode( $debug, $dest = “stdout” ){
if( $debug === false ){
$this->debug = false;
return true;
}

$this->debug = true;
$this->debugMode = $debug;
$this->debugDest = $dest;
}

/**
* start the server
*
* @access public
* @param int $maxClients
*/
function start(){
$this->initFD = @socket_create( AF_INET, SOCK_STREAM, 0 );
if( !$this->initFD )
die( “patServer: Could not create socket.” );

// adress may be reused
socket_setopt( $this->initFD, SOL_SOCKET, SO_REUSEADDR, 1 );

// bind the socket
if( !@socket_bind ( $this->initFD, $this->domain, $this->port ) ){
@socket_close( $this->initFD );
die( “patServer: Could not bind socket to “.$this->domain.” on port “.$this->port.” ( “.$this->getLastSocketError( $this->initFd ).” ).” );
}

// listen on selected port
if( !@socket_listen ( $this->initFD, $this->maxQueue ) )
die( “patServer: Could not listen ( “.$this->getLastSocketError( $this->initFd ).” ).” );

$this->sendDebugMessage( “Listening on port “.$this->port.”. Server started at “.date( “H:i:s”, time() ) );

// this allows the shutdown function to check whether the server is already shut down
$GLOBALS["_patServerStatus"] = “running”;
// this ensures that the server will be sutdown correctly
register_shutdown_function( array( $this, “shutdown” ) );

if( method_exists( $this, “onStart” ) )
$this->onStart();

$this->serverInfo["started"] = time();
$this->serverInfo["status"] = “running”;

while( true ){
$readFDs = array();
array_push( $readFDs, $this->initFD );

// fetch all clients that are awaiting connections
for( $i = 0; $i < count( $this->clientFD ); $i++ )
if( isset( $this->clientFD[$i] ) )
array_push( $readFDs, $this->clientFD[$i] );

// block and wait for data or new connection
$ready = @socket_select( $readFDs, $this->null, $this->null, NULL );

if( $ready === false ){
$this->sendDebugMessage( “socket_select failed.” );
$this->shutdown();
}

// check for new connection
if( in_array( $this->initFD, $readFDs ) ){
$newClient = $this->acceptConnection( $this->initFD );

// check for maximum amount of connections
if( $this->maxClients > 0 ){
if( $this->clients > $this->maxClients ){
$this->sendDebugMessage( “Too many connections.” );

if( method_exists( $this, “onConnectionRefused” ) )
$this->onConnectionRefused( $newClient );

$this->closeConnection( $newClient );
}
}

if( –$ready <= 0 )
continue;
}

// check all clients for incoming data
for( $i = 0; $i < count( $this->clientFD ); $i++ ){
if( !isset( $this->clientFD[$i] ) )
continue;

if( in_array( $this->clientFD[$i], $readFDs ) ){
$data = $this->readFromSocket( $i );

// empty data => connection was closed
if( !$data ){
$this->sendDebugMessage( “Connection closed by peer” );
$this->closeConnection( $i );
}else{
$this->sendDebugMessage( “Received “.trim( $data ).” from “.$i );

if( method_exists( $this, “onReceiveData” ) )
$this->onReceiveData( $i, $data );
}
}
}
}
}

/**
* read from a socket
*
* @access private
* @param integer $clientId internal id of the client to read from
* @return string $data data that was read
*/
function readFromSocket( $clientId ){
// start with empty string
$data = “”;

// read data from socket
while( $buf = socket_read( $this->clientFD[$clientId], $this->readBufferSize ) ){
$data .= $buf;

$endString = substr( $buf, – strlen( $this->readEndCharacter ) );
if( $endString == $this->readEndCharacter )
break;
if( $buf == NULL )
break;
}

if( $buf === false )
$this->sendDebugMessage( “Could not read from client “.$clientId.” ( “.$this->getLastSocketError( $this->clientFD[$clientId] ).” ).” );

return $data;
}

/**
* accept a new connection
*
* @access public
* @param resource &$socket socket that received the new connection
* @return int $clientID internal ID of the client
*/
function acceptConnection( &$socket ){
for( $i = 0 ; $i <= count( $this->clientFD ); $i++ ){
if( !isset( $this->clientFD[$i] ) || $this->clientFD[$i] == NULL ){
$this->clientFD[$i] = socket_accept( $socket );
socket_setopt( $this->clientFD[$i], SOL_SOCKET, SO_REUSEADDR, 1 );
$peer_host = “”;
$peer_port = “”;
socket_getpeername( $this->clientFD[$i], $peer_host, $peer_port );
$this->clientInfo[$i] = array(
“host” => $peer_host,
“port” => $peer_port,
“connectOn” => time()
);
$this->clients++;

$this->sendDebugMessage( “New connection ( “.$i.” ) from “.$peer_host.” on port “.$peer_port );

if( method_exists( $this, “onConnect” ) )
$this->onConnect( $i );
return $i;
}
}
}

/**
* check, whether a client is still connected
*
* @access public
* @param integer $id client id
* @return boolean $connected true if client is connected, false otherwise
*/
function isConnected( $id ){
if( !isset( $this->clientFD[$id] ) )
return false;
return true;
}

/**
* close connection to a client
*
* @access public
* @param int $clientID internal ID of the client
*/
function closeConnection( $id ){
if( !isset( $this->clientFD[$id] ) )
return false;

if( method_exists( $this, “onClose” ) )
$this->onClose( $id );

$this->sendDebugMessage( “Closed connection ( “.$id.” ) from “.$this->clientInfo[$id]["host"].” on port “.$this->clientInfo[$id]["port"] );

@socket_close( $this->clientFD[$id] );
$this->clientFD[$id] = NULL;
unset( $this->clientInfo[$id] );
$this->clients–;
}

/**
* shutdown server
*
* @access public
*/
function shutDown(){
if( $GLOBALS["_patServerStatus"] != “running” )
exit;
$GLOBALS["_patServerStatus"] = “stopped”;

if( method_exists( $this, “onShutdown” ) )
$this->onShutdown();

$maxFD = count( $this->clientFD );
for( $i = 0; $i < $maxFD; $i++ )
$this->closeConnection( $i );

@socket_close( $this->initFD );

$this->sendDebugMessage( “Shutdown server.” );
exit;
}

/**
* get current amount of clients
*
* @access public
* @return int $clients amount of clients
*/
function getClients(){
return $this->clients;
}

/**
* send data to a client
*
* @access public
* @param int $clientId ID of the client
* @param string $data data to send
* @param boolean $debugData flag to indicate whether data that is written to socket should also be sent as debug message
*/
function sendData( $clientId, $data, $debugData = true ){
if( !isset( $this->clientFD[$clientId] ) || $this->clientFD[$clientId] == NULL )
return false;

if( $debugData )
$this->sendDebugMessage( “sending: \”" . $data . “\” to: $clientId” );

if( !@socket_write ( $this->clientFD[$clientId], $data ) )
$this->sendDebugMessage( “Could not write ‘”.$data.”‘ client “.$clientId.” ( “.$this->getLastSocketError( $this->clientFD[$clientId] ).” ).” );
}

/**
* send data to all clients
*
* @access public
* @param string $data data to send
* @param array $exclude client ids to exclude
*/
function broadcastData( $data, $exclude = array(), $debugData = true ){
if( !empty( $exclude ) && !is_array( $exclude ) )
$exclude = array( $exclude );

for( $i = 0; $i < count( $this->clientFD ); $i++ ){
if( isset( $this->clientFD[$i] ) && $this->clientFD[$i] != NULL && !in_array( $i, $exclude ) ){
if( $debugData )
$this->sendDebugMessage( “sending: \”" . $data . “\” to: $i” );

if( !@socket_write ( $this->clientFD[$i], $data ) )
$this->sendDebugMessage( “Could not write ‘”.$data.”‘ client “.$i.” ( “.$this->getLastSocketError( $this->clientFD[$i] ).” ).” );
}
}
}

/**
* get current information about a client
*
* @access public
* @param int $clientId ID of the client
* @return array $info information about the client
*/
function getClientInfo( $clientId ){
if( !isset( $this->clientFD[$clientId] ) || $this->clientFD[$clientId] == NULL )
return false;
return $this->clientInfo[$clientId];
}

/**
* send a debug message
*
* @access private
* @param string $msg message to debug
*/
function sendDebugMessage( $msg ){
if( !$this->debug )
return false;

$msg = date( “Y-m-d H:i:s”, time() ) . ” ” . $msg;

switch( $this->debugMode ){
case “text”:
$msg = $msg.”\n”;
break;
case “html”:
$msg = htmlspecialchars( $msg ) . “<br />\n”;
break;
}

if( $this->debugDest == “stdout” || empty( $this->debugDest ) ){
echo $msg;
flush();
return true;
}

error_log( $msg, 3, $this->debugDest );
return true;
}

/**
* return string for last socket error
*
* @access public
* @return string $error last error
*/
function getLastSocketError( &$fd ){
$lastError = socket_last_error( $fd );
return “msg: ” . socket_strerror( $lastError ) . ” / Code: “.$lastError;
}
function onReceiveData($ip,$data){
$this->broadcastData( $data,array(), true );
}
}
$patServer = new patServer();
$patServer->start();
?>

window.name和JSONP的跨域实现(jQuery)【推荐】

1,window.name
原理:
name 在浏览器环境中是一个全局/window对象的属性,且当在 iframe 中加载新页面时,name 的属性值依旧保持不变。
但 此时 name 属性仅对相同域名的 iframe 可访问 ,所以第二次加载时需要加载本地的文件(空文件也可),把name引到本地来使用。
当然iframe的name使用完后,应该把iframe删除(涉及动态创建iframe和删除iframe)。请看例子2。


本地端:
function sendData(){
var state = 0;
var $iframe = $(“#iframeId”);
$iframe.bind(‘load’, function(){
if(state === 1){
var data = $(this)[0].contentWindow.name;//iframe的src已经转到同域,所以可以访问iframe的name了.即:实现了跨域.
$(“#oldFish”).html( “你获取的数据是:”+data );
}else if(state === 0){
state = 1;
$(this)[0].contentWindow.location = “none.html”;//$(this)[0].contentWindow相当于iframe的window,再次触发iframe的onload事件
}
});
$iframe.attr(“src”,”http://www.cssrain.cn/test.html“);//第一次触发iframe的onload事件。
}
sendData();



远程访问端:
window.name = “CssRain”;



源文件下载:
http://www.cssrain.cn/demo/windowname.rar


一个简单的插件:
jQuery.getWindowName = function(url,callback){
if(!url || typeof url !== ’string’){return;}
url += (url.indexOf(‘?’) > 0 ? ‘&’ : ‘?’) + ‘remote=’+(+new Date());
var frame = $(‘<iframe style=”display:none;”></iframe>’).appendTo(“body”);
var state = 0;
frame.load(function(){
if(state === 0){
state = 1;
frame[0].contentWindow.location = “none.html”;
}else{
var data = frame[0].contentWindow.name;
frame.remove();
if(callback && typeof callback === ‘function’){
callback(data);
}
}
}).attr(“src”,url);
};


调用方法:
$.getWindowName(“http://cssrain.cn/test.html“,function(data){
alert(data);
});


2,JSONP

function jsonp(url,callback,name, query)
{
if (url.indexOf(“?”) > -1)
url += “&jsonp=”
else
url += “?jsonp=”
url += name + “&”;
if (query)
url += encodeURIComponent(query) + “&”;
url += new Date().getTime().toString(); // prevent caching

var script = document.createElement(“script”);
script.setAttribute(“src”,url);
script.setAttribute(“type”,”text/javascript”);
document.body.appendChild(script);
}

function callbackFunction(Result)
{
alert(Result.x + ” ” + Result.y) ;
}


调用jsonp函数,去服务器请求,地址此时是这样:
http://someserver.com/mypage.aspx?jsonp=callbackFunction

如果服务器想返回一个:
{ “x”: 10, “y”: 15} 这样的数据。

那么可以利用后台语言获取jsonp的值,然后拼接返回,代码如下:
string Callback = Request.QueryString["jsonp"];
Response.Write(Callback + “( {\”x\”:10 , \”y\”:15} );”);

前台接收的数据是:
callbackFunction( { “x”: 10, “y”: 15} );


这个数据正好执行了 先前 定义好的函数:
function callbackFunction(Result)
{
alert(Result.x + ” ” + Result.y) ;
}


关于jsonp的文章:
http://www.west-wind.com/Weblog/posts/107136.aspx

25个PHP游戏编程脚本代码【推荐】

比较工整的查看页面:http://www.chinaz.com/Program/PHP/121410103H009_9.html

本文介绍的脚本易于理解、使用简单并可以快速掌握。简单的掷骰器许多游戏和游戏系统都需要骰子。让我们先从简单的部分入手:掷一个六面骰子。实际上,滚动一个六面骰子就是从 1 到 6 之间选择一个随机数字。在 PHP 中,这十分简单:echo rand(1,6);。在许多情况下,这基本上很简单。但是在处理机率游戏时,我们需要一些更好的实现。PHP 提供了更好的随机数字生成器:mt_rand()。在不深入研究两者差别的情况下,可以认为 mt_rand 是一个更快、更好的随机数字生成器:echo mt_rand(1,6);。如果把该随机数字生成器放入函数中,则效果会更好。清单 1. 使用 mt_rand() 随机数字生成器函数  function roll () {   return mt_rand(1,6);   }   echo roll(); 然后可以把需要滚动的骰子类型作为参数传递给函数。清单 2. 将骰子类型作为参数传递  function roll ($sides) {   return mt_rand(1,$sides);   }   echo roll(6); // roll a six-sided die   echo roll(10); // roll a ten-sided die   echo roll(20); // roll a twenty-sided die 从这里开始,我们可以继续根据需要一次滚动多个骰子,返回结果数组;也可以一次性滚动多个不同类型的骰子。但是大多数任务都可以使用这个简单的脚本。随机名称生成器如果正在运行游戏、编写故事或者一次性创建大批字符,有时会疲于应付不断出现的新名字。让我们看一看可用于解决此问题的一个简单随机名称生成器。首先,让我们创建两个简单数组 – 一个用于名字,一个用于姓氏。清单 3. 名字和姓氏的两个简单数组  $male = array(   ”William”,   ”Henry”,   ”Filbert”,   ”John”,   ”Pat”,   );   $last = array(   ”Smith”,   ”Jones”,   ”Winkler”,   ”Cooper”,   ”Cline”,   ); 然后就可以从每个数组中选择一个随机元素:echo $male[array_rand($male)] . ‘ ‘ . $last[array_rand($last)];。要一次性提取多个名称,只需混合数组并根据需要提取。清单 4. 混合名称数组  shuffle($male);   shuffle($last);   for ($i = 0; $i <= 3; $i++) {   echo $male[$i] . ‘ ‘ . $last[$i];   } 基于此基本概念,我们可以创建保存名字和姓氏的文本文件。如果在文本文件的每一行中存放一个名字,则可以轻松地用换行符分隔文件内容以构建源代码数组。清单 5. 创建名称的文本文件  $male = explode(‘\n’, file_get_contents(‘names.female.txt’));   $last = explode(‘\n’, file_get_contents(‘names.last.txt’)); 构建或查找一些好的名字文件(代码归档 中附带了一些文件),此后我们绝不再需要为名字烦恼。场景生成器利用构建名字生成器使用的相同基本原理,我们可以构建场景生成器。此生成器不但在角色扮演游戏中十分有用,而且在需要用到伪随机环境集合(可用于角色扮演、即兴创作、写作等情况)的情况下也十分有用。我最喜欢的游戏之一,Paranoia 在其 GM Pack 中包括了 “任务混合器(mission blender)”。任务混合器可用于在快速滚动骰子时整合完整任务。让我们整合自己的场景生成器。考虑以下场景:您醒来后发现自己迷失于丛林中。您知道自己必须赶去纽约,但是不知道原因。您可以听到附近的狗叫声及清晰的敌方搜寻者的声音。您浑身发冷、不住颤抖,而且没有武器。该场景中的每一句话都介绍场景的特定方面: “您醒来后发现自己迷失于丛林中” – 这句话将建立设置。 “您知道自己必须赶去纽约” – 这句话将描述目标。 “您可以听到狗叫声” – 这句话将介绍敌人。 “您浑身发冷、不住颤抖,而且没有武器” – 这句话将添加复杂度。就像创建名字和姓氏的文本文件一样,首先分别创建设置、目标、敌人和复杂度的文本文件。代码归档中附带了样例文件。在拥有这些文件后,生成场景的代码与生成名称的代码基本相同。清单 6. 生成场景  $settings = explode(“\n”, file_get_contents(’scenario.settings.txt’));   $objectives = explode(“\n”, file_get_contents(’scenario.objectives.txt’));   $antagonists = explode(“\n”, file_get_contents(’scenario.antagonists.txt’));   $complicati**** = explode(“\n”, file_get_contents(’scenario.complicati****.txt’));   shuffle($settings);   shuffle($objectives);   shuffle($antagonists);   shuffle($complicati****);   echo $settings[0] . ‘ ‘ . $objectives[0] . ‘ ‘ . $antagonists[0] . ‘ ‘   . $complicati****[0] . ”
\n”; 我们可以通过添加新文本文件向场景中添加元素,也可能希望添加多重复杂度。添加到基本文本文件中的内容越多,场景随时间的变化就越多。牌组创建器(Deck builder)和装备(shuffler)如果您要玩纸牌并且要处理与纸牌相关的脚本,我们需要用装备中的工具整合一副牌组构建器。首先,让我们构建一副标准纸牌。需要构建两个数组 – 一个用于保存同花色的组牌,而另一个用于保存牌面。如果稍后需要添加新组牌或牌类型,则这样做将获得很好的灵活性。清单 7. 构建一副标准扑克牌  $suits = array (   ”Spades”, “Hearts”, “Clubs”, “Diamonds”   );   $faces = array (   ”Two”, “Three”, “Four”, “Five”, “Six”, “Seven”, “Eight”,   ”Nine”, “Ten”, “Jack”, “Queen”, “King”, “Ace”   ); 然后构建一副牌数组来保存所有纸牌值。只需使用一对 foreach 循环即可完成此操作。清单 8. 构建一副牌数组  $deck = array();   foreach ($suits as $suit) {   foreach ($faces as $face) {   $deck[] = array (“face”=>$face, “suit”=>$suit);   }   } 在构建了一副扑克牌数组后,我们可以轻松地洗牌并随机抽出一张牌。清单 9. 洗牌并随机抽出一张牌  shuffle($deck);   $card = array_shift($deck);   echo $card['face'] . ‘ of ‘ . $card['suit']; 现在,我们就获得了抽取多副牌或构建多层牌盒(multideck shoe)的捷径。胜率计算器:发牌由于构建扑克牌时会分别跟踪每张牌的牌面和花色,因此可以通过编程方式利用这副牌来计算得到特定牌的几率。首先每只手分别抽出五张牌。清单 10. 每只手抽出五张牌  $hands = array(1 => array(), 2=>array());   for ($i = 0; $i < 5; $i++) {   $hands[1][] = implode(” of “, array_shift($deck));   $hands[2][] = implode(” of “, array_shift($deck));   } 然后可以查看这副牌,看看剩余多少张牌以及抽到特定牌的机率是多少。查看剩余的牌数十分简单。只需要计算 $deck 数组中包含的元素数。要获得抽到特定牌的机率,我们需要一个函数来遍历整副牌并估算其余牌以查看是否匹配。清单 11. 计算抽到特定牌的几率  function calculate_odds($draw, $deck) {   $remaining = count($deck);   $odds = 0;   foreach ($deck as $card) {   if ( ($draw['face'] == $card['face'] && $draw['suit'] ==   $card['suit'] ) ||   ($draw['face'] == ” && $draw['suit'] == $card['suit'] ) ||   ($draw['face'] == $card['face'] && $draw['suit'] == ” ) ) {   $odds++;   }   }   return $odds . ‘ in ‘ $remaining;   } 现在可以选出尝试抽出的牌。为了简单起见,传入看上去类似某张牌的数组。我们可以查找特定的一张牌。清单 12. 查找指定的一张牌  $draw = array(‘face’ => ‘Ace’, ’suit’ => ‘Spades’);   echo implode(” of “, $draw) . ‘ : ‘ . calculate_odds($draw, $deck); 或者可以查找指定牌面或花色的牌。清单 13. 查找指定牌面或花色的牌  $draw = array(‘face’ => ”, ’suit’ => ‘Spades’);   $draw = array(‘face’ => ‘Ace’, ’suit’ => ”); 简单的扑克发牌器现在已经得到牌组构建器和一些工具,可以帮助计算出抽出特定卡的机率,我们可以整合一个真正简单的发牌器来进行发牌。出于本例的目的,我们将构建一个可以抽出五张牌的发牌器。发牌器将从整副牌中提供五张牌。使用数字指定需要放弃哪些牌,并且发牌器将用一副牌中的其他牌替换这些牌。我们无需指定发牌限制或特殊规则,但是您可能会发现这些是非常有益的个人经验。如上一节所示,生成并洗牌,然后每只手五张牌。按数组索引显示这些牌,以便可以指定返回哪些牌。您可以使用表示要替换哪些牌的复选框来完成此操作。清单 14. 使用复选框表示要替换的牌  foreach ($hand as $index =>$card) {   echo ”   ” . $card['face'] . ‘ of ‘ . $card['suit'] . ”
“;   } 然后,计算输入 array $_POST['card'],查看哪些牌已被选择用于替换。清单 15. 计算输入  $i = 0;   while ($i < 5) {   if (isset($_POST['card'][$i])) {   $hand[$i] = array_shift($deck);   }   } 使用此脚本,您可以尝试找到处理特定一组牌的最佳方法。 Hangman 游戏 Hangman 实质上是一款猜字游戏。给定单词的长度,我们使用有限的几次机会猜这个单词。如果猜出了出现在该单词中的一个字母,则填充该字母出现的所有位置。在猜错若干次(通常为六次)后,您就输了比赛。要构建一个简陋的 hangman 游戏,我们需要从单词列表开始。现在,让我们把单词列表制作成一个简单的数组。清单 16. 创建单词列表  $words = array (   ”giants”,   ”triangle”,   ”particle”,   ”birdhouse”,   ”minimum”,   ”flood”   ); 使用前面介绍的技术,我们可以把这些单词移动到外部单词列表文本文件中,然后根据需要导入。在得到单词列表后,需要随机选出一个单词,将每个字母显示为空,然后开始猜测。我们需要在每次进行猜测时跟踪正确和错误的猜测。只需序列化猜测数组并在每次猜测时传递它们,就可实现跟踪目的。如果需要阻止人们通过查看页面源代码侥幸猜对,则需要执行一些更安全的操作。构建数组以保存字母和正确/错误的猜测。对于正确的猜测,我们将用字母作为键并用句点作为值填充数组。清单 17. 构建保存字母和猜测结果的数组  $letters = array(‘a’,'b’,'c’,'d’,'e’,'f’,'g’,'h’,'i’,'j’,'k’,'l’,'m’,'n’,'o’,   ’p',’q',’r',’s’,'t’,'u’,'v’,'w’,'x’,'y’,'z’);   $right = array_fill_keys($letters, ‘.’);   $wrong = array(); 现在需要一些代码来评估猜测并在完成猜字游戏的过程中显示该单词。清单 18. 评估猜测并显示进度  if (stristr($word, $guess)) {   $show = ”;   $right[$guess] = $guess;   $wordletters = str_split($word);   foreach ($wordletters as $letter) {   $show .= $right[$letter];   }   } else {   $show = ”;   $wrong[$guess] = $guess;   if (count($wrong) == 6) {   $show = $word;   } else {   foreach ($wordletters as $letter) {   $show .= $right[$letter];   }   }   } 在源代码归档 中,可以看到如何序列化猜测数组并将该数组从一次猜测传递到另一次猜测中。纵横字谜助手我知道这样做不合适,但是有时在玩纵横拼字谜时,您不得不费劲地找出以 C 开头并以 T 结尾、包含五个字母的单词。使用为 Hangman 游戏构建的相同单词列表,我们可以轻松地搜索符合某个模式的单词。首先,找到一种传输单词的方法。为了简单起见,用句点替换缺少的字母:$guess = “c…t”;。由于正则表达式将把句点处理为单个字符,因此我们可以轻松地遍历单词列表以查找匹配。清单 19. 遍历单词列表  foreach ($words as $word) {   if (preg_match(“/^” . $_POST['guess'] . “$/”,$word)) {   echo $word . ”
\n”;   }   } 根据单词列表的质量及猜测的准确度,我们应当能够得到合理的单词列表以用于可能的匹配。您必须自己决定 “表示 ‘不按规则玩’ 的由五个字母组成的单词” 的谜底是 “chest” 还是 “cheat”。米德里比斯米德里比斯是一款文字游戏,玩家在游戏中得到一个简短的故事并用同一类型的不同单词替换主要类型的单词,从而创建同一个故事的更无聊的新版本。阅读以下文本:”I was walking in the park when I found a lake. I jumped in and swallowed too much water. I had to go to the hospital.” 开始用其他单词标记替换单词类型。开始和结束标记带有下划线用于阻止意外的字符串匹配。清单 20. 用单词标记替换单词类型  $text = “I was _VERB_ing in the _PLACE_ when I found a _NOUN_.   I _VERB_ed in, and _VERB_ed too much _NOUN_. I had to go to the _PLACE_.”; 接下来,创建几个基本单词列表。对于本例,我们也不会做得太复杂。清单 21. 创建几个基本单词列表  $verbs = array(‘pump’, ‘jump’, ‘walk’, ’swallow’, ‘crawl’, ‘wail’, ‘roll’);   $places = array(‘park’, ‘hospital’, ‘arctic’, ‘ocean’, ‘grocery’, ‘basement’,   ’attic’, ’sewer’);   $nouns = array(‘water’, ‘lake’, ’spit’, ‘foot’, ‘worm’,   ’dirt’, ‘river’, ‘wankel rotary engine’); 现在可以重复地评估文本来根据需要替换标记。清单 22. 评估文本  while (preg_match(“/(_VERB_)|(_PLACE_)|(_NOUN_)/”, $text, $matches)) {   switch ($matches[0]) {   case ‘_VERB_’ :   shuffle($verbs);   $text = preg_replace($matches[0], current($verbs), $text, 1);   break;   case ‘_PLACE_’ :   shuffle($places);   $text = preg_replace($matches[0], current($places), $text, 1);   break;   case ‘_NOUN_’ :   shuffle($nouns);   $text = preg_replace($matches[0], current($nouns), $text, 1);   break;   }   }   echo $text; 很明显,这是一个简单而粗糙的示例。单词列表越精确,并且花在基本文本上的时间越多,结果就越好。我们已经使用了文本文件创建名称列表及基本单词列表。使用相同原则,我们可以创建按类型划分的单词列表并使用这些单词列表创建更加变化多端的米德里比斯游戏。乐透机全部选中乐透的六个正确号码 — 退一步说 — 在统计学上是不可能的。不过,许多人仍然花钱去玩,而且如果您喜欢号码,则查看趋势图可能很有趣。让我们构建一个脚本,该脚本将允许跟踪赢奖号码并在列表中提供选择次数最少的 6 个号码。(免责声明:这不会帮助您中乐透奖,因此请不要花钱购买奖券。这只是为了娱乐)。把赢奖的乐透选择保存到文本文件中。用逗号分隔各个号码并把每组号码放在单独一行中。使用换行符分隔文件内容并使用逗号分隔行后,可以得到类似清单 23 的内容。清单 23. 把选择的赢奖乐透保存到文本文件中  $picks = array(   array(‘6′, ‘10′, ‘18′, ‘21′, ‘34′, ‘40′),   array(‘2′, ‘8′, ‘13′, ‘22′, ‘30′, ‘39′),   array(‘3′, ‘9′, ‘14′, ‘25′, ‘31′, ‘35′),   array(‘11′, ‘12′, ‘16′, ‘24′, ‘36′, ‘37′),   array(‘4′, ‘7′, ‘17′, ‘26′, ‘32′, ‘33′)   ); 很明显,这不足以成为绘制统计数据的基本文件。但是它是一个开端,并且足以演示基本原理。设置一个基本数组以保存选择范围。例如,如果选择 1 到 40 之间(例如,$numbers = array_fill(1,40,0);)的号码,则遍历我们的选择,递增相应的匹配值。清单 24. 遍历选择  foreach ($picks as $pick) {   foreach ($pick as $number) {   $numbers[$number]++;   }   } 最后,根据值将号码排序。此操作应当会把最少选择的号码放在数组的前部。清单 25. 根据值将号码排序  asort($numbers);   $pick = array_slice($numbers,0,6,true);   echo implode(‘,’, array_keys($pick)); 通过有规律地向包含中奖号码列表的文本文件添加实际的乐透中奖号码,可以发现选号的长期趋势。查看某些号码的出现频率十分有趣。

使用.htaccess的重定向部署二级域名【推荐】

www.domain.com直接到根目录下

别的二级域名如
xyz.domain.com到根目录下的xyz目录。

实现:
配置apache的http.conf文件,
->取消164行LoadModule rewrite_module modules/mod_rewrite.so前的#号
->文件最后
RewriteEngine on

RewriteCond %{HTTP_HOST} ^www\.xieye\.com$
RewriteRule ^(.+) /$1 [L]

RewriteCond %{HTTP_HOST} [^.]+\.xieye\.com$
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule ([^.]+)\.xieye\.com(.*) /$1$2

20070704再度修改

# 配置 Apache重定向模块 用于二级域名解析 xieye 20080704
RewriteEngine on


# 主站,url是www.xieye.com
RewriteCond %{HTTP_HOST} ^www\.xieye\.com$
RewriteRule ^(.+) /$1 [L]

# 专业子站 url是gongsi.xieye.com/
# 专业子站,进入 例如 specialty/gongsi/ 这样的子目录,但是,如果是找js,css,upload等,则再度返回主站目录
RewriteCond %{HTTP_HOST} ^(gongsi|fangdichan|haishang|hunyin|jianshe|jingji|jingrong|laodong|shewai|sunhai)\.xieye\.com$
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule ([^.]+)\.xieye\.com(.*) /specialty/$1$2 [C]
RewriteRule /specialty/[^/]+/(ajax|cp|css|fckeditor|images|js|upload)/(.+) /$1/$2 [L]

# 地区分站 url是nanjinglaw.xieye.com/
# 地区分站,进入 例如 area/nanjing/ 这样的子目录,但是,如果是找js,css,upload等,则再度返回主站目录
RewriteCond %{HTTP_HOST} ^([^.]+)law\.xieye\.com$
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule ([^.]+)law\.xieye\.com(.*) /area/$1$2 [C]
RewriteRule /area/[^/]+/(ajax|cp|css|fckeditor|images|js|upload)/(.+) /$1/$2 [L]

# 博客 url是zhangsan.xieye.com/
# 博客,进入 例如 blog/z/h/angsan/ 这样的子目录,但是,如果是找js,css,upload等,则再度返回主站目录
RewriteCond %{HTTP_HOST} [^.]+\.xieye\.com$
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule (a-z0-9)(a-z0-9)([^.]+)\.xieye\.com(.*) /demoblog/$1/$2/$3$4
RewriteRule /demoblog/[^/]+/[^/]+/[^/]+/(ajax|cp|css|fckeditor|images|js|upload)/(.+) /$1/$2 [L]

来源:http://cnqhoo.javaeye.com/demoblog/401567

Zend Framework整合smarty方法

index.php入口文件:

<?php
error_reporting(E_ALL|E_STRICT);
date_default_timezone_set(‘Asia/Shanghai’);
define(‘WEB_ROOT’, ‘http://localhost/zendframework/’);//为分页设置的变量,pagestyle.phtml文件要用
set_include_path(‘.’ .PATH_SEPARATOR .’./library’.PATH_SEPARATOR .’./application/models/’.PATH_SEPARATOR . get_include_path());

require_once ‘Zend/Loader.php’;
Zend_Loader::registerAutoload();//设置 Zend Framework 自动载入类文件

//配制 smarty 参数
include “./public/scripts/Smarty/Smarty.class.php”;//引入smarty文件
$smarty = new Smarty();
$smarty -> template_dir = “./application/views/scripts/”;//设置模板显示路径
$smarty -> compile_dir = “./application/views/scripts/templates_c”;

$smarty -> left_delimiter = “<{“;
$smarty -> right_delimiter = “}>”;
$registry = Zend_Registry::getInstance();
$registry->set(’smarty’,$smarty);


//配置 数据库 参数,并连接数据库
$config=new Zend_Config_Ini(‘./application/config/config.ini’,null, true);
Zend_Registry::set(‘config’,$config);
$dbAdapter=Zend_Db::factory($config->general->db->adapter,$config->general->db->config->toArray());
$dbAdapter->query(“SET NAMES {$config->general->db->config->charset}”);
Zend_Db_Table::setDefaultAdapter($dbAdapter);
Zend_Registry::set(‘dbAdapter’,$dbAdapter);
Zend_Registry::set(‘dbprefix’,$config->general->db->config->prefix);
//设置控制器
$frontController =Zend_Controller_Front::getInstance();
$frontController->setBaseUrl(‘/zendframework’)//设置基本路径
->setParam(‘noViewRenderer’, true)
->setControllerDirectory(‘./application/controllers’)
->throwExceptions(true)
->dispatch();

SmartyController .php路由文件
<?php
class SmartyController extends Zend_Controller_Action
{
function init() {
$this->registry = Zend_Registry::getInstance();
$this->view = $this->registry['smarty'];
$baseurl = $this->_request->getBaseUrl();
$this->view->assign(‘baseurl’,$baseurl);
}
function indexAction(){
$title = “运行成功了。”;
$this->view->assign(‘title’,$title);
$this->view->display(’smarty/index.phtml’);
}

}
最后就是模板文件了:
在zendframework\application\views\scripts\smarty文件夹里面建模板index.phtml:

这里是smarty模板:<{$title}>

这是简单了整合smarty.其实写成插件的形式更好,我正在整理。。。

本人也是刚刚学习Zend framework ,有很多不足之处,高手飘过就可以了。

好了,该吃饭了,插件也写好了。其实很简单,看下面吧。


index.php入口文件:
<?php
error_reporting(E_ALL|E_STRICT);
date_default_timezone_set(‘Asia/Shanghai’);
define(‘WEB_ROOT’, ‘http://localhost/zendframework/’);//为分页设置的变量,pagestyle.phtml文件要用
set_include_path(‘.’ .PATH_SEPARATOR .’./library’.PATH_SEPARATOR .’./application/models/’.PATH_SEPARATOR . get_include_path());

require_once ‘Zend/Loader.php’;
Zend_Loader::registerAutoload();//设置Zend Framework 自动载入类文件

//Smarty的配制在Custom/Controller/Plugin/Smarty.php文件中
Custom_Controller_Plugin_Smarty::SmartyView();//smarty的配制文件

//配置数据库参数,并连接数据库
$config=new Zend_Config_Ini(‘./application/config/config.ini’,null, true);
Zend_Registry::set(‘config’,$config);
$dbAdapter=Zend_Db::factory($config->general->db->adapter,$config->general->db->config->toArray());
$dbAdapter->query(“SET NAMES {$config->general->db->config->charset}”);
Zend_Db_Table::setDefaultAdapter($dbAdapter);
Zend_Registry::set(‘dbAdapter’,$dbAdapter);
Zend_Registry::set(‘dbprefix’,$config->general->db->config->prefix);
//设置控制器
$frontController =Zend_Controller_Front::getInstance();
$frontController->setBaseUrl(‘/zendframework’)//设置基本路径
->setParam(‘noViewRenderer’, true)
->setControllerDirectory(‘./application/controllers’)
->throwExceptions(true)
->dispatch();
SmartyController .php路由文件和上面的一样。
在zendframework\application\views\scripts\smarty文件夹里面建模板index.phtml:和上面的一样。

最后就是在zendframework\library\Custom\Controller\Plugin中的插件文件了Smarty.php:

<?php
/**
* Zend_Controller_Plugin_Abstract
*/
//require_once ‘Zend/Controller/Plugin/Abstract.php’;
class Custom_Controller_Plugin_Smarty extends Zend_Controller_Plugin_Abstract
{
public static function SmartyView(){
//配制smarty参数
include “./public/scripts/Smarty/Smarty.class.php”;//引入smarty文件
$smarty = new Smarty();
$smarty -> template_dir = “./application/views/scripts/”;//设置模板显示路径
$smarty -> compile_dir = “./application/views/scripts/templates_c”;
$smarty -> left_delimiter = “<{“;
$smarty -> right_delimiter = “}>”;
$registry = Zend_Registry::getInstance();
$registry->set(’smarty’,$smarty);
}
}

简单吧。
来源:zendchina

Zend Framework整合smarty方法

index.php入口文件:

<?php
error_reporting(E_ALL|E_STRICT);
date_default_timezone_set(‘Asia/Shanghai’);
define(‘WEB_ROOT’, ‘http://localhost/zendframework/’);//为分页设置的变量,pagestyle.phtml文件要用
set_include_path(‘.’ .PATH_SEPARATOR .’./library’.PATH_SEPARATOR .’./application/models/’.PATH_SEPARATOR . get_include_path());

require_once ‘Zend/Loader.php’;
Zend_Loader::registerAutoload();//设置Zend Framework 自动载入类文件

//配制smarty参数
include “./public/scripts/Smarty/Smarty.class.php”;//引入smarty文件
$smarty = new Smarty();
$smarty -> template_dir = “./application/views/scripts/”;//设置模板显示路径
$smarty -> compile_dir = “./application/views/scripts/templates_c”;

$smarty -> left_delimiter = “<{“;
$smarty -> right_delimiter = “}>”;
$registry = Zend_Registry::getInstance();
$registry->set(’smarty’,$smarty);


//配置数据库参数,并连接数据库
$config=new Zend_Config_Ini(‘./application/config/config.ini’,null, true);
Zend_Registry::set(‘config’,$config);
$dbAdapter=Zend_Db::factory($config->general->db->adapter,$config->general->db->config->toArray());
$dbAdapter->query(“SET NAMES {$config->general->db->config->charset}”);
Zend_Db_Table::setDefaultAdapter($dbAdapter);
Zend_Registry::set(‘dbAdapter’,$dbAdapter);
Zend_Registry::set(‘dbprefix’,$config->general->db->config->prefix);
//设置控制器
$frontController =Zend_Controller_Front::getInstance();
$frontController->setBaseUrl(‘/zendframework’)//设置基本路径
->setParam(‘noViewRenderer’, true)
->setControllerDirectory(‘./application/controllers’)
->throwExceptions(true)
->dispatch();

SmartyController.php路由文件
<?php
class SmartyController extends Zend_Controller_Action
{
function init() {
$this->registry = Zend_Registry::getInstance();
$this->view = $this->registry['smarty'];
$baseurl = $this->_request->getBaseUrl();
$this->view->assign(‘baseurl’,$baseurl);
}
function indexAction(){
$title = “运行成功了。”;
$this->view->assign(‘title’,$title);
$this->view->display(’smarty/index.phtml’);
}

}
最后就是模板文件了:
在zendframework\application\views\scripts\smarty文件夹里面建模板index.phtml:

这里是smarty模板:<{$title}>

这是简单了整合smarty.其实写成插件的形式更好,我正在整理。。。

本人也是刚刚学习Zend framework ,有很多不足之处,高手飘过就可以了。

好了,该吃饭了,插件也写好了。其实很简单,看下面吧。


index.php入口文件:
<?php
error_reporting(E_ALL|E_STRICT);
date_default_timezone_set(‘Asia/Shanghai’);
define(‘WEB_ROOT’, ‘http://localhost/zendframework/’);//为分页设置的变量,pagestyle.phtml文件要用
set_include_path(‘.’ .PATH_SEPARATOR .’./library’.PATH_SEPARATOR .’./application/models/’.PATH_SEPARATOR . get_include_path());

require_once ‘Zend/Loader.php’;
Zend_Loader::registerAutoload();//设置Zend Framework 自动载入类文件

//Smarty的配制在Custom/Controller/Plugin/Smarty.php文件中
Custom_Controller_Plugin_Smarty::SmartyView();//smarty的配制文件

//配置数据库参数,并连接数据库
$config=new Zend_Config_Ini(‘./application/config/config.ini’,null, true);
Zend_Registry::set(‘config’,$config);
$dbAdapter=Zend_Db::factory($config->general->db->adapter,$config->general->db->config->toArray());
$dbAdapter->query(“SET NAMES {$config->general->db->config->charset}”);
Zend_Db_Table::setDefaultAdapter($dbAdapter);
Zend_Registry::set(‘dbAdapter’,$dbAdapter);
Zend_Registry::set(‘dbprefix’,$config->general->db->config->prefix);
//设置控制器
$frontController =Zend_Controller_Front::getInstance();
$frontController->setBaseUrl(‘/zendframework’)//设置基本路径
->setParam(‘noViewRenderer’, true)
->setControllerDirectory(‘./application/controllers’)
->throwExceptions(true)
->dispatch();
SmartyController.php路由文件和上面的一样。
在zendframework\application\views\scripts\smarty文件夹里面建模板index.phtml:和上面的一样。

最后就是在zendframework\library\Custom\Controller\Plugin中的插件文件了Smarty.php:

<?php
/**
* Zend_Controller_Plugin_Abstract
*/
//require_once ‘Zend/Controller/Plugin/Abstract.php’;
class Custom_Controller_Plugin_Smarty extends Zend_Controller_Plugin_Abstract
{
public static function SmartyView(){
//配制smarty参数
include “./public/scripts/Smarty/Smarty.class.php”;//引入smarty文件
$smarty = new Smarty();
$smarty -> template_dir = “./application/views/scripts/”;//设置模板显示路径
$smarty -> compile_dir = “./application/views/scripts/templates_c”;
$smarty -> left_delimiter = “<{“;
$smarty -> right_delimiter = “}>”;
$registry = Zend_Registry::getInstance();
$registry->set(’smarty’,$smarty);
}
}

简单吧。
来源:zendchina