页面载入中...
首页 » 网页技术

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″,”字符串”);可实现各种字符编码的转换。

js 设为首页 加入收藏 兼容FF和IE浏览器

//兼容FF和IE浏览器的设为首页、本页收藏

<script type=”text/javascript” language=”javascript”>
//兼容FF和IE浏览器的设为首页、本页收藏
function AddFavorite(sURL, sTitle) {
try {
window.external.addFavorite(sURL, sTitle);
} catch (e) {
try {
window.sidebar.addPanel(sTitle, sURL, “”);
} catch (e) {
alert(“加入收藏失败,请使用Ctrl+D进行添加”);
}
}
}
function SetHome(obj,vrl) {
try {
obj.style.behavior=’url(#default#homepage)’;obj.setHomePage(vrl);
} catch(e) {
if(window.netscape) {
try {
netscape.security.PrivilegeManager.enablePrivilege(“UniversalXPConnect”);
} catch (e) {
alert(“此操作被浏览器拒绝!\n请在浏览器地址栏输入”about:config”并回车\n然后将[signed.applets.codebase_principal_support]设置为’true’”);
}
var prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch);
prefs.setCharPref(‘browser.startup.homepage’,vrl);
}
}
}
</script>

<a onclick=”AddFavorite(‘http://www.sina.com.cn’,document.title)” style=”cursor:hand”>加入收藏</a>
<a onclick=”SetHome(this,’http://www.sina.com.cn’)” >设为首页</a>

Technorati : ,
Del.icio.us : ,
Zooomr : ,
Flickr : ,

SEO工具,站长必备

SEO工具,站长必备

内容与结构工具 可以模拟蜘蛛抓取指定网页,包括Text、Link、Keywords及Description信息等。
http://www.webconfs.com/search-engine-spider-simulator.php

页面相似度检测工具

检验两个页面的相似度(如果相似度达80%以上,将可能受到惩罚)
http://www.webconfs.com/similar-page-checker.php

Sitemap 制作工具

在线创建 Sitemap 网站地图文件

中文: http://www.xinqj.com/sitemap/sitemap.asp

英文: http://www.xml-sitemaps.com/

在线创建Sitemap可能会有一些限制,推荐使用下面的离线工具:

Google SiteMapBuilder .Net

Sitemap 网站地图文件创建软件,可以很方便XML格式、txt格式的Sitemap
http://www.seobbs.net/read.php?tid=10620

注意:此软件工作于.Net 1.1 环境,2.0下无法运行。

综合查询工具

网站收录查询

同时查询网站在Google、百度、Yahoo等8个搜索引擎中的收录情况
http://tool.cndw.com/Shoulu/Index.asp

关键词排名查询
在Google、百度、Yahoo等多个搜索引擎中查询指定网页、指定关键词的排名情况
http://www.seores.com/search/keywordrank.asp

搜索引擎优化 监视器( Monitor) SEO

一个仅300多KB的小软件,可以在多个搜索引擎中,查询多个关键词的排名情况,并记录历史排名情况供参考
http://www.seobbs.net/read.php?tid=2490

域名Whois/IP工具

最详细的Whois/IP工具,包括很多实用数据。
http://whois.domaintools.com

关键词工具

Google Adwords关键词工具

查询指定关键词的扩展匹配,并可以根据词义进行扩展,显示出搜索量、竞争度和受欢迎度
https://adwords.google.com/select/KeywordToolExternal

百度相关搜索

按热门程度排序,列出指定关键词相关的扩展匹配及热门程度
http://d.baidu.com/rs.php

百度指数

以图表的形式显示指定关键词在百度中的关注度、媒体关注度,登录后可以定义列表。
http://index.baidu.com/

关键词密度分析工具

分析指定关键词在指定页面中出现的次数,及相应的百分比密度

中文: http://tool.cndw.com/Seo/Key_Density.asp

英文: http://www.keyworddensity.com/

关键词热门排行及指数

谷歌热榜: http://www.google.cn/rebang

百度排行榜: http://top.baidu.com

Overture关键词工具: http://inventory.overture.com/d/searchinventory/suggestion/

Yahoo排行榜: http://misc.yahoo.com.cn/top_index.html

搜狗指数: http://www.sogou.com/top/

搜搜龙虎榜: http://www.soso.com/lhb/s_i_sosolhb.shtml


Google相关工具

Google网站管理员工具

Google为站长提供的一个很有价值的平台,是站长了解Google、与Google对话的窗口。
https://www.google.com/webmasters/tools/

Google Analytics

Google推出的免费分析服务,对市场营销和内容优化上提供很多专业报表
http://www.google.com/analytics/zh-CN/

Google Dance 查询工具

不仅可以查询Dance情况,还可以通过E-mail及时获得每月google dance通知
http://www.seochat.com/googledance/

GOOGLE PageRank工具

SEO Chat.com提供的免费工具,可以查询在Google多个服务器上的PR值
http://www.seochat.com/seo-tools/future-pagerank

SEO Chat.com提供的免费工具,可以同时查询多个域名的PR值
http://www.seochat.com/seo-tools/pagerank-lookup/

SEO Chat.com提供的免费工具,可以查询网站中各页面的PR情况
http://www.seochat.com/seo-tools/pagerank-search/

Google PR历史更新时间表

查看Google从2000年至今,更新PR的具体时间和周期时长
http://www.seocompany.ca/pagerank/page-rank-update-list.html

链接工具

链接广泛度检测工具

反向链接查询工具,同时支持Google、百度、Yahoo等多个搜索引擎
http://tool.cndw.com/LinkIn/Index.asp

查询Google中反链的工具,可以抓取文本标题和链接(中文标题显示的是乱码)
http://www.webconfs.com/google-backlink-checker.php

Yahoo新推出的链接检查工具,可以查询网站中所有被检索的页面以及反向链接情况
http://siteexplorer.search.yahoo.com/

无效链接检查工具

Xenu Link Sleuth
http://www.seobbs.net/read.php?tid=2307

W3C GLink Checker
http://validator.w3.org/checklink

其他工具

国外主要搜索引擎和人工目录的关系表
2个Flash,解析国外主流搜索引擎与人工目录的关系,对海外推广很有帮助
http://www.seobbs.net/read.php?tid=911

网站历史查询工具
美国互联网档案馆(The Internet Archive)保存了自1996年开始,借助Alexa搜索引擎获取的网站资料
http://web.archive.org/collections/web/advanced.html

Alexa世界排名查询
http://alexa.chinaz.com/

源自: http://www.seobbs.net/read.php?tid=1396 樂思蜀

前端开发大众手册(包括工具、网址、经验等)

转自蓝色 http://home.blueidea.com/space.php?uid=353293&do=blog&id=12766

前端开发大众手册(包括工具、网址、经验等)

标签 : 手册 网址 工具 经验 开发 10小时前

一直觉得前端开发缺个手册,这是个体力活。不过总得有人来干。

今天闲来无事,把一些工具(online和client的)、常用网址、以及经验总结等罗列出来和大家分享下。这个标题起地大了点,肯定会有很多地方没列到,包括类目的分法也可能考虑不周,所以还请大家积极补充指正,可以直接留言,也可以发邮件给我(sorrycc#gmail.com)。之所以加上”大众”两字,因为以下资源对于高手来说可能早就很熟悉了。

另外想提一句,工具是死的,好不好用得看你会不会用。比如Firefox、Fiddler等,除了显而易见的功能以外,都有一些小的技巧,掌握了可以让你事半功倍。

更新记录:

  • [20081025] 第一版

快捷导航:

另外还搞了个Firefox插件《 前端开发工具集 》,把资源整合到一个菜单下,方便查询。数据放在线上(Google AppEngine),速度应该会有保证,更新也会比较方便哈,见图。

在线工具集

常用Firefox插件

IE下的调试工具

  • Fiddle2 — 非常强悍的一款http流查看工具,默认支持IE,其他浏览器可以设置将{Document}\Scripts\BrowserPAC.js设为代理进行使用。Firefox下可用上述”Fiddler 开关”进行快速切换。支持 插件
  • IE Developer Toolbar — 查看元素、禁用缓存、禁用CSS\JS、Outline元素、查看生成的源码等功能,IE8自带了一个加强版的。
  • Microsoft Script Debugger + Companion.JS — 调试JS用,虽然报错还是有误差,但是我已经满足了。安装顺序是:Microsoft Script Debugger,Companion.JS,在”IE选项-高级”里 取消禁用脚本调试
  • 多版本IE共存两种方案:
    • IE7/8 + IE Tester — 大众型配置,可以基本满足日常需要。
    • IE6 + Internet Explorer Collection — 在IE 6用户占绝对优势以及IE 6神奇bug满天飞的时代,我还是推荐这种方案,因为只有神奇的原装IE 6,才能抵挡运营神奇的问题。另外如果还有其他机器可供支配的话,建议再装个IE 8 + IE Tester,因为IE 8下的Developer Toolbar还是有很大改进的,调试起来会方便一些。
  • 以下三个软件相对不重要些:

参考手册

批处理工具

IDE及其他工具

Bookmarklet(右键另存)

  • Firebug Lite 官方介绍
  • Xray 官方介绍
  • MRI 官方介绍
  • <A href=”javascript:”+ window.document.documentElement.outerHTML+ ”+ window.document.documentElement.outerHTML+ “”&gt;查看生成的源码,<A href=”javascript:(function(){var w=window.open(‘about:blank’);w.document.write(“+ window.document.documentElement.outerHTML+ ”+ window.document.documentElement.outerHTML+ “);})()”&gt;打开新窗口查看生成的源码 — for IE

开发者社区及权威网站

推荐订阅的博客和网站(排名不分先后)

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

动态加载script标签的js

下面为动态加载script标签的js

JavaScript代码

1. <script>

2.

3. var element = document.createElement(“script”);

4.

5. function createScript(compId,dataId){

6. element.src = “http://othersite.com/json.php?comp_id=” + compId + “&data_id=” + dataId + “”;

7. element.type = “text/javascript”;

8. element.language = “javascript”;

9. }

10.

11. function writeContent(){

12. alert(productJSON.product[0].name);

13. }

14.

15. window.onload = function(){

16. createScript(1,2);

17. document.getElementsByTagName(“head”)[0].appendChild(element);

18. }

19.

20. if(document.all){

21. element.onreadystatechange = function(){//IE用

22. var state = element.readyState;

23. if (state == “loaded” || state == “interactive” || state == “complete”) {

24. writeContent();

25. }

26. };

27.

28. } else {

29. element.onload = function() {//FF用

30. writeContent();

31. };

32. }

33.

34.

35. </script>

下面是json.php echo出来的内容
var productJSON = {‘product’: [
{'name' : '物件名1'},
{'building' : '建物名1'},
{'address' : '5'}
]
};

用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