Archive for 七月, 2005

smarty中方括号“[]”不能嵌套吗?

七月 28th, 2005 by admin

前提:$typearr是一个数组,dict_list是SQL select 返回的数组,Smarty version 2.6.6

过程:

1. {$typearr[$dict_list[l].type]} 编译出错;

2. {$typearr.$dict_list[l].type} 编译后:_tpl_vars['typearr'][$this->_tpl_vars['dict_list']][$this->_sections['l']['index']]['type']; ?>

3. pass:{$typearr[$row.type]} 编译后:_tpl_vars['typearr'][$this->_tpl_vars['row']['type']]; ?>;
4. error:{$typearr.$row.type} 编译后:_tpl_vars['typearr'][$this->_tpl_vars['row']]['type']; ?>,但PHP返回如下错误[2] Illegal offset type (在 cachedefaultcompile%%4A^4AD^4ADE8EAC%%xxxxx.inc.tpl.php 的第 69 行);

分析:

因为在Manual上看到: {$foo[bar]} <– syntax only valid in a section loop, see {section}
故猜想 变量$row.type是数值型 可能是上面3.PASS的原因,但实际试验发现这个位置换成$row.title(字符串型)也是可以通过的;

目前怀疑是Smarty的编译过程没有考虑 方括号嵌套。。。。。。。

HonestQiao
版主 - 法师

——————————————————————————–

实际上,是你自己没有考虑好。

为什么呢? 模板本来是给美工用的,你想一想,美工学会这个,你还不如让他直接学西PHP开发

_________________

普及Apache,从WAPM开始
激动人心的 WAPM3 开发计划,正式启动

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

wsswan
骑士
——————————————————————————–

xlight 写到:
<– syntax only valid in a section loop, see {section}
故猜想 变量$row.type是数值型 可能是上面3.PASS的原因,但实际试验发现这个位置换成$row.title(字符串型)也是可以通过的;

目前怀疑是Smarty的编译……….

{$foo[bar]} <– syntax only valid in a section loop, see {section}
不是已经写的很明白了么,让您使用 section 来处理此类操作。

写 Smarty 的人,尤其是写 Smarty_Compiler.class.php 的是大师级人物,不信您就试试看能不能看懂源码:)
=======================================================

carset
精灵王
——————————————————————————–

实际上呢 smarty 由于太注重逻辑分离.结果导致太复杂.已经被我抛弃了.

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

wsswan
骑士

——————————————————————————–

carset 写到:
实际上呢 smarty 由于太注重逻辑分离.结果导致太复杂.已经被我抛弃了.

我跟您正好相反,由于 Smarty 严格而强大的模板处理能力,使我在日常应用中可以对模板进行随心所欲的修改和限制,所以我已经离不开它了:)

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

csona
光明使者

——————————————————————————–

smarty好哇

_________________
没办法就是这么菜

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

xlight
新手上路

——————————————————————————–

引用:
模板大概这么写:
代码:

代码:

{=section name=out loop=$list=}
代号:{=$list[out].id=}

姓名:{=$list[out].name=}

性别:{=if $list[out].sex eq 'm'=}男{=else=}女{=/if=}

{=/section=}

这样就能基本完成一个关联数组的循环

我想请问一下如果我想将上例中的
代码:
{=if $list[out].sex eq 'm'=}男{=else=}女{=/if=}

换成
代码:
{=$sexarr[$list[out].sex]=}

其中:$sexarr = array ( "m" => "男" , "f" => "女" )

是否可以实现?

其实这里使用plugin.modifier 或 临时变量 或 连续多个if都可以解决,只是想讨论一下,谢谢各位的解答

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

wsswan
骑士

——————————————————————————–

如果功能复杂就用 register_function ,象过滤这样的功能用 register_modifier 就成了。

代码:
代码:
require_once 'libs/Smarty.class.php';

$list = array('m','f','x','');
$sm = new smarty;
$sm->template_dir = './templates/';
$sm->compile_dir = './templates_c/';

$sm->register_modifier('filter','customer');
$sm->assign('list',$list);
$sm->display('list.tpl');

//////////////////////////////////////
function customer($string = null){

$out = null;
switch ($string){
case null:
$out = '空';break;
case 'm':
$out = '男';break;
case 'f':
$out = '女';break;
default:
$out = '两性';
}

return $out;

}
?>

模板:
代码:

{section name=out loop=$list}
{$list[out]|filter}

{/section}

最后输出:


两性

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

xlight
新手上路

——————————————————————————-

谢谢楼上
我现在用foreach 替代 section解决了这个问题,不过还是不能理解为什么Smarty中不能嵌套“方括号”。
代码:

{foreach from=$dict_list item=dict_item}

{$typearr[$dict_item.type]} |
{$dict_item.subtype} |
{$dict_item.id} |
{$dict_item.title}
{/foreach}

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

wsswan
骑士

——————————————————————————–

大概是在编译之前 没有 eval() 就直接 preg_match_all() 了吧。你可以做一个试演来看看,用 left_delimiter 和 right_delimiter 来包围你想匹配的变量,例如:{$typearr[{$dict_item.type}]}

:)

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

作者 留言
xlight
新手上路

——————————————————————————–
印象中 left_delimiter 和 right_delimiter 也是不能嵌套的吧
=======================================================

wsswan
骑士
——————————————————————————–
兄台说的太对了,刚才饿的有些头晕,所以没想就说了……实际上嵌套 left_delimiter 和 right_delimiter Smarty 根本就解析不出来,

在 Smarty_Compile.class.php 的 426 行加入一句:
echo $template_tag;echo '
';

然后将 Smarty.class.php 的 1088 行屏蔽掉(不报错)

程序不变,模板:
代码:

{section name=inner loop=$count}
{$tsil[$count[inner]]} “ {$tsil[{$count[inner]}]}

{/section}

显示的是这样:
代码:

section name=inner loop=$count
$tsil[$count[inner]]
$tsil[{$count[inner]
/section
“ ]}
“ ]}
“ ]}
“ ]}

可见,{$tsil[{$count[inner]}]} 根本就没匹配对。追根溯源还是 Smarty_Compile.class.php 的第 273 行 代码:

preg_match_all("~{$ldq}s*(.*?)s*{$rdq}~s", $source_content, $_match);

匹配的问题。下回回答问题得先吃饭,要不然丢人啊:)
=======================================================

wsswan
骑士

——————————————————————————–

不过从根本上讲开来,嵌套是最不应该出现在模板上的结构,因为 section(foreach),本身就是为了解决这个问题而诞生的。

我推荐任何时候都用 section ,因为它比 foreach 多了 index、rownum、index_prev、index_next、first、last 等属性,这样在拓展方面就有着非常广阔的前景。您可以看看 Smarty_Compile.class.php 中的 function _compile_section_start() 和 function _compile_section_start() 两个函数:)

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

xlight
新手上路

——————————————————————————–

谢谢 wsswan ,
那个什么 “听君一席话,胜读十年书”阿
:)

[转]苹果公司CEO在斯坦福毕业典礼上的演讲

七月 28th, 2005 by xLight

苹果公司CEO在斯坦福毕业典礼上的演讲
Submitted by aggie on 星期日, 七月 24, 2005 - 20:33 人生感悟

一直就很崇拜Jobs,这篇稿子讲的非常好。
Stanford Report, June 14, 2005
You’ve got to find what you love,’ Jobs says
This is the text of the Commencement address by Steve Jobs, CEO of Apple Computer and of Pixar Animation Studios, delivered on June 12, 2005.
I am honored to be with you today at your commencement from one of the finest universities in the world. I never graduated from college. Truth be told, this is the closest I’ve ever gotten to a college graduation. Today I want to tell you three stories from my life. That’s it. No big deal. Just three stories.
The first story is about connecting the dots.
I dropped out of Reed College after the first 6 months, but then stayed
around as a drop-in for another 18 months or so before I really quit. So
why did I drop out?
It started before I was born. My biological mother was a young, unwed college graduate student, and she decided to put me up for adoption. She felt very strongly that I should be adopted by college graduates, so everything was all set for me to be adopted at birth by a lawyer and his wife. Except that when I popped out they decided at the last minute that they really wanted a girl. So my parents, who were on a waiting list, got a call in the middle of the night asking: “We have an unexpected baby boy; do you want him?” They said: “Of course.” My biological mother later found out that my mother had never graduated from college and that my father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents promised that I would someday go to college.
And 17 years later I did go to college. But I naively chose a college that was almost as expensive as Stanford, and all of my working-class parents’ savings were being spent on my college tuition. After six months, I couldn’t see the value in it. I had no idea what I wanted to do with my life and no idea how college was going to help me figure it out. And here I was spending all of the money my parents had saved their entire life. So I decided to drop out and trust that it would all work
out OK. It was pretty scary at the time, but looking back it was one of the best decisions I ever made. The minute I dropped out I could stop taking the required classes that didn’t interest me, and begin dropping in on the ones that looked interesting.
It wasn’t all romantic. I didn’t have a dorm room, so I slept on the floor in friends’ rooms, I returned coke bottles for the 5¢ deposits to buy food with, and I would walk the 7 miles across town every Sunday night to get one good meal a week at the Hare Krishna temple. I loved it. And much of what I stumbled into by following my curiosity and intuition turned out to be priceless later on. Let me give you one example:

Reed College at that time offered perhaps the best calligraphy instruction in the country. Throughout the campus every poster, every label on every drawer, was beautifully hand calligraphed. Because I had dropped out and didn’t have to take the normal classes, I decided to take a calligraphy class to learn how to do this. I learned about serif and san serif typefaces, about varying the amount of space between different letter combinations, about what makes great typography great. It was beautiful, historical, artistically subtle in a way that science can’t capture, and I found it fascinating.
None of this had even a hope of any practical application in my life. But ten years later, when we were designing the first Macintosh computer, it all came back to me. And we designed it all into the Mac. It was the first computer with beautiful typography. If I had never dropped in on that single course in college, the Mac would have never had multiple typefaces or proportionally spaced fonts. And since Windows just copied the Mac, its likely that no personal computer would have them. If I had never dropped out, I would have never dropped in on this calligraphy class, and personal computers might not have the wonderful typography that they do. Of course it was impossible to connect the dots looking forward when I was in college. But it was very, very clear looking backwards ten years later.
Again, you can’t connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something - your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.

My second story is about love and loss.
I was lucky – I found what I loved to do early in life. Woz and I
started Apple in my parents garage when I was 20. We worked hard, and in 10 years Apple had grown from just the two of us in a garage into a $2
billion company with over 4000 employees. We had just released our finest creation - the Macintosh - a year earlier, and I had just turned 30. And then I got fired. How can you get fired from a company you started? Well, as Apple grew we hired someone who I thought was very talented to run the company with me, and for the first year or so things went well. But then our visions of the future began to diverge and eventually we had a falling out. When we did, our Board of Directors sided with him. So at 30 I was out. And very publicly out. What had been the focus of my entire adult life was gone, and it was devastating.
I really didn’t know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down - that I had dropped the baton as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and I even thought about running away from the valley.
But something slowly began to dawn on me – I still loved what I did. The turn of events at Apple had not changed that one bit. I had been rejected, but I was still in love. And so I decided to start over. I didn’t see it then, but it turned out that getting fired from Apple was the best thing that could have ever happened to me. The heaviness of being successful was replaced by the lightness of being a beginner again, less sure about everything. It freed me to enter one of the most creative periods of my life.
During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I returned to Apple, and the technology we developed at NeXT is at the heart of Apple’s current renaissance. And Laurene and I have a wonderful family together.
I’m pretty sure none of this would have happened if I hadn’t been fired from Apple. It was awful tasting medicine, but I guess the patient needed it. Sometimes life hits you in the head with a brick. Don’t lose faith. I’m convinced that the only thing that kept me going was that I loved what I did. You’ve got to find what you love. And that is as true for your work as it is for your lovers. Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven’t found it yet, keep looking. Don’t settle. As with all matters of the heart, you’ll know when you find it. And, like any great relationship, it just gets better and better as the years roll on. So keep looking until you find it. Don’t settle.

My third story is about death.
When I was 17, I read a quote that went something like: “If you live each day as if it was your last, someday you’ll most certainly be right.” It made an impression on me, and since then, for the past 33 years, I have looked in the mirror every morning and asked myself: “If today were the last day of my life, would I want to do what I am about to do today?” And whenever the answer has been “No” for too many days in a row, I know I need to change something.
Remembering that I’ll be dead soon is the most important tool I’ve ever encountered to help me make the big choices in life. Because almost everything – all external expectations, all pride, all fear of embarrassment or failure - these things just fall away in the face of death, leaving only what is truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are already naked. There is no reason not to follow your heart.
About a year ago I was diagnosed with cancer. I had a scan at 7:30 in the morning, and it clearly showed a tumor on my pancreas. I didn’t even know what a pancreas was. The doctors told me this was almost certainly a type of cancer that is incurable, and that I should expect to live no longer than three to six months. My doctor advised me to go home and get my affairs in order, which is doctor’s code for prepare to die. It means to try to tell your kids everything you thought you’d have the next 10 years to tell them in just a few months. It means to make sure everything is buttoned up so that it will be as easy as possible for your family. It means to say your goodbyes.
I lived with that diagnosis all day. Later that evening I had a biopsy, where they stuck an endoscope down my throat, through my stomach and into my intestines, put a needle into my pancreas and got a few cells from the tumor. I was sedated, but my wife, who was there, told me that when they viewed the cells under a microscope the doctors started crying because it turned out to be a very rare form of pancreatic cancer that is curable with surgery. I had the surgery and I’m fine now.
This was the closest I’ve been to facing death, and I hope its the closest I get for a few more decades. Having lived through it, I can now say this to you with a bit more certainty than when death was a useful but purely intellectual concept:
No one wants to die. Even people who want to go to heaven don’t want to die to get there. And yet death is the destination we all share. No one has ever escaped it. And that is as it should be, because Death is very likely the single best invention of Life. It is Life’s change agent. It clears out the old to make way for the new. Right now the new is you, but someday not too long from now, you will gradually become the old and be cleared away. Sorry to be so dramatic, but it is quite true.
Your time is limited, so don’t waste it living someone else’s life. Don’t be trapped by dogma - which is living with the results of other people’s thinking. Don’t let the noise of other’s opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.
When I was young, there was an amazing publication called The Whole Earth Catalog, which was one of the bibles of my generation. It was created by a fellow named Stewart Brand not far from here in Menlo Park, and he brought it to life with his poetic touch. This was in the late 1960’s, before personal computers and desktop publishing, so it was all made with typewriters, scissors, and polaroid cameras. It was sort of like Google in paperback form, 35 years before Google came along: it was idealistic, and overflowing with neat tools and great notions.
Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find yourself hitchhiking on if you were so adventurous. Beneath it were the words: “Stay Hungry. Stay Foolish.” It was their farewell message as they signed off. Stay Hungry. Stay Foolish. And I have always wished that for myself. And now, as you graduate to begin anew, I wish that for you.

Stay Hungry. Stay Foolish.

Thank you all very much.

 

主题: 网上的译文,翻译的大体尚可
作者: aggie
日期: 周日, 2005-07-24 20:35

我今天很荣幸能和你们一起参加毕业典礼,斯坦福大学是世界上最好的大学之一。我从来没有从大学中毕业。说实话,今天也许是在我的生命中离大学毕业最近的一天了。今天我想向你们讲述我生活中的三个故事。不是什么大不了的事情,只是三个故事而已。

第一个故事是关于如何把生命中的点点滴滴串连起来。

我在Reed大学读了六个月之后就退学了,但是在十八个月以后——我真正的作出退学决定之前,我还经常去学校。我为什么要退学呢?

故事从我出生的时候讲起。我的亲生母亲(biological mother)是一个年轻的,没有结婚的大学毕业生。她决定让别人收养我, 她十分想让我被大学毕业生收养。所以在我出生的时候,她已经做好了一切的准备工作,能使得我被一个律师和他的妻子所收养。但是她没有料到,当我出生之后, 律师夫妇突然决定他们想要一个女孩。所以我的生养父母(他们还在我亲生父母的观察名单上)突然在半夜接到了一个电话:“我们现在这儿有一个不小心生出来的男婴,你们想要他吗?”他们回答道: “当然!”但是我亲生母亲随后发现,我的养母从来没有上过大学,我的父亲甚至从没有读过高中。她拒绝签这个收养合同。只是在几个月以后,我的父母答应她一定要让我上大学,那个时候她才同意。

在十七岁那年,我真的上了大学。但是我很愚蠢的选择了一个几乎和你们斯坦福大学一样贵的学校, 我父母还处于蓝领阶层,他们几乎把所有积蓄都花在了我的学费上面。在六个月后, 我已经看不到其中的价值所在。我不知道我想要在生命中做什么,我也不知道大学能帮助我找到怎样的答案。但是在这里,我几乎花光了我父母这一辈子的所有积蓄。所以我决定要退学,我觉得这是个正确的决定。不能否认,我当时确实非常的害怕, 但是现在回头看看,那的确是我这一生中最棒的一个决定。在我做出退学决定的那一刻, 我终于可以不必去读那些令我提不起丝毫兴趣的课程了。然后我还可以去修那些看起来有点意思的课程。

但是这并不是那么罗曼蒂克。我失去了我的宿舍,所以我只能在朋友房间的地板上面睡觉,我去捡5美分的可乐瓶子,仅仅为了填饱肚子, 在星期天的晚上,我需要走七英里的路程,穿过这个城市到Hare Krishna寺庙(注:位于纽约Brooklyn下城),只是为了能吃上饭——这个星期唯一一顿好一点的饭。但是我喜欢这样。我跟着我的直觉和好奇心走, 遇到的很多东西,此后被证明是无价之宝。让我给你们举一个例子吧:

Reed大学在那时提供也许是全美最好的美术字课程。在这个大学里面的每个海报, 每个抽屉的标签上面全都是漂亮的美术字。因为我退学了, 没有受到正规的训练, 所以我决定去参加这个课程,去学学怎样写出漂亮的美术字。我学到了san serif 和serif字体, 我学会了怎么样在不同的字母组合之中改变空格的长度, 还有怎么样才能作出最棒的印刷式样。那是一种科学永远不能捕捉到的、美丽的、真实的艺术精妙, 我发现那实在是太美妙了。

当时看起来这些东西在我的生命中,好像都没有什么实际应用的可能。但是十年之后,当我们在设计第一台Macintosh电脑的时候,就不是那样了。我把当时我学的那些家伙全都设计进了Mac。那是第一台使用了漂亮的印刷字体的电脑。如果我当时没有退学, 就不会有机会去参加这个我感兴趣的美术字课程, Mac就不会有这么多丰富的字体,以及赏心悦目的字体间距。那么现在个人电脑就不会有现在这么美妙的字型了。当然我在大学的时候,还不可能把从前的点点滴滴串连起来,但是当我十年后回顾这一切的时候,真的豁然开朗了。

再次说明的是,你在向前展望的时候不可能将这些片断串连起来;你只能在回顾的时候将点点滴滴串连起来。所以你必须相信这些片断会在你未来的某一天串连起来。你必须要相信某些东西:你的勇气、目的、生命、因缘。这个过程从来没有令我失望(let me down),只是让我的生命更加地与众不同而已。

我的第二个故事是关于爱和损失的.

我非常幸运, 因为我在很早的时候就找到了我钟爱的东西。Woz和我在二十岁的时候就在父母的车库里面开创了苹果公司。我们工作得很努力, 十年之后, 这个公司从那两个车库中的穷光蛋发展到了超过四千名的雇员、价值超过二十亿的大公司。在公司成立的第九年,我们刚刚发布了最好的产品,那就是 Macintosh。我也快要到三十岁了。在那一年, 我被炒了鱿鱼。你怎么可能被你自己创立的公司炒了鱿鱼呢? 嗯,在苹果快速成长的时候,我们雇用了一个很有天分的家伙和我一起管理这个公司, 在最初的几年,公司运转的很好。但是后来我们对未来的看法发生了分歧, 最终我们吵了起来。当争吵不可开交的时候, 董事会站在了他的那一边。所以在三十岁的时候, 我被炒了。在这么多人的眼皮下我被炒了。在而立之年,我生命的全部支柱离自己远去, 这真是毁灭性的打击。

在最初的几个月里,我真是不知道该做些什么。我把从前的创业激情给丢了, 我觉得自己让与我一同创业的人都很沮丧。我和David Pack和Bob Boyce见面,并试图向他们道歉。我把事情弄得糟糕透顶了。但是我渐渐发现了曙光, 我仍然喜爱我从事的这些东西。苹果公司发生的这些事情丝毫的没有改变这些, 一点也没有(did not changed one bit)。我被驱逐了,但是我仍然钟爱它。所以我决定从头再来。

我当时没有觉察, 但是事后证明, 从苹果公司被炒是我这辈子发生的最棒的事情。因为,作为一个成功者的极乐感觉被作为一个创业者的轻松感觉所重新代替: 对任何事情都不那么特别看重。这让我觉得如此自由, 进入了我生命中最有创造力的一个阶段。

在接下来的五年里, 我创立了一个名叫NeXT的公司, 还有一个叫Pixar的公司, 然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“玩具总动员”,Pixar现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple收购了 NeXT, 然后我又回到了Apple公司。我们在NeXT发展的技术在Apple的复兴之中发挥了关键的作用。我还和Laurence 一起建立了一个幸福的家庭。

我可以非常肯定,如果我不被Apple开除的话, 这其中一件事情也不会发生的。这个良药的味道实在是太苦了,但是我想病人需要这个药。有些时候, 生活会拿起一块砖头向你的脑袋上猛拍一下。不要失去信心。我很清楚唯一使我一直走下去的,就是我做的事情令我无比钟爱。你需要去找到你所爱的东西。对于工作是如此, 对于你的爱人也是如此。你的工作将会占据生活中很大的一部分。你只有相信自己所做的是伟大的工作, 你才能怡然自得。如果你现在还没有找到, 那么继续找、不要停下来、全心全意的去找, 当你找到的时候你就会知道的。就像任何真诚的关系, 随着岁月的流逝只会越来越紧密。所以继续找,直到你找到它,不要停下来!

我的第三个故事是关于死亡的.

当我十七岁的时候, 我读到了一句话:“如果你把每一天都当作生命中最后一天去生活的话,那么有一天你会发现自己是正确的。”这句话给我留下了深刻的印象。从那时开始,过了 33年,我在每天早晨都会对着镜子问自己:“如果今天是我生命中的最后一天, 你会不会完成你今天想做的事情呢?”当答案连续很多次被给予“不是”的时候, 我知道自己需要改变某些事情了。

“记住你即将死去”是我一生中遇到的最重要箴言。它帮我指明了生命中重要的选择。因为几乎所有的事情, 包括所有的荣誉、所有的骄傲、所有对难堪和失败的恐惧,这些在死亡面前都会消失。我看到的是留下的真正重要的东西。

你有时候会思考你将会失去某些东西,“记住你即将死去”是我知道的避免这些想法的最好办法。你已经赤身裸体了, 你没有理由不去跟随自己的心一起跳动。

大概一年以前, 我被诊断出癌症。我在早晨七点半做了一个检查, 检查清楚的显示在我的胰腺有一个肿瘤。我当时都不知道胰腺是什么东西。医生告诉我那很可能是一种无法治愈的癌症, 我还有三到六个月的时间活在这个世界上。我的医生叫我回家, 然后整理好我的一切, 那就是医生准备死亡的程序。那意味着你将要把未来十年对你小孩说的话在几个月里面说完.;那意味着把每件事情都搞定, 让你的家人会尽可能轻松的生活;那意味着你要说“再见了”。

我整天和那个诊断书一起生活。后来有一天早上我作了一个活切片检查,医生将一个内窥镜从我的喉咙伸进去,通过我的胃, 然后进入我的肠子, 用一根针在我的胰腺上的肿瘤上取了几个细胞。我当时很镇静,因为我被注射了镇定剂。但是我的妻子在那里, 后来告诉我,当医生在显微镜地下观察这些细胞的时候他们开始尖叫, 因为这些细胞最后竟然是一种非常罕见的、可以用手术治愈的胰腺癌细胞。我做了这个手术, 现在我痊愈了。

那是我最接近死亡的时候, 我还希望这也是以后的几十年最接近的一次。从死亡线上又活了过来, 死亡对我来说,只是一个有用但是纯粹是知识上的概念的时候,我可以更肯定一点地对你们说:

没有人愿意死, 即使人们想上天堂, 人们也不会为了去那里而死。但是死亡是我们每个人共同的终点。从来没有人能够逃脱它,也应该如此。因为死亡就是生命中最好的一个发明。它将旧的清除以便给新的让路。你们现在是新的, 但是从现在开始不久以后, 你们将会逐渐的变成旧的然后被清除。我很抱歉这很具有戏剧性, 但是这十分的真实。

你们的时间很有限, 所以不要将他们浪费在重复其他人的生活上。不要被教条束缚,那意味着你和其他人思考的结果一起生活。不要被其他人喧嚣的观点掩盖你真正的内心的声音。还有最重要的是, 你要有勇气去听从你直觉和心灵的指示——它们在某种程度上知道你想要成为什么样子,所有其他的事情都是次要的。

当我年轻的时候, 有一本叫做“整个地球的目录”振聋发聩的杂志,它是我们那一代人的圣经之一。它是一个叫Stewart Brand的家伙在离这里不远的Menlo Park书写的, 他象诗一般神奇地将这本书带到了这个世界。那是六十年代后期, 在个人电脑出现之前, 所以这本书全部是用打字机,、剪刀还有偏光镜制作的。有点像用软皮包装的google, 在google出现三十五年之前:这是理想主义的,其中有许多灵巧的工具和伟大的想法。

Stewart和他的伙伴出版了几期的“整个地球的目录”,当它完成了自己使命的时候, 他们做出了最后一期的目录。那是在七十年代的中期, 你们的时代。在最后一期的封底上是清晨乡村公路的照片(如果你有冒险精神的话,你可以自己找到这条路的),在照片之下有这样一段话:“保持饥饿,保持愚蠢。”这是他们停止了发刊的告别语。“保持饥饿,保持愚蠢。”我总是希望自己能够那样,现在, 在你们即将毕业,开始新的旅程的时候, 我也希望你们能做到这样:

保持饥饿,保持愚蠢。(Stay Hungry. Stay Foolish.)

非常感谢你们。

[转]年轻人的发展目标:做一个领导者(leader)

七月 28th, 2005 by admin

年轻人的发展目标:做一个领导者(leader),
Submitted by wwccss on 星期六, 七月 23, 2005 - 16:45 人生感悟

前一段时间和朋友们聊天,讲起现在年轻人的发展目标应该是什么?我套用了一个演义小说里面经常用的一个词语能文能武来回答这个问题。

能文

能文表现在以下几个方面:
第一、良好的沟通能力。你要很好的理解对方所要表达的意思,同时也要仅可能清楚简洁的把你的意思表达出来。
第二、良好的文字功夫。文字功夫不求优美,但求清楚。你要用清楚简洁的文字把你的想法整理下来,你要拥有归纳,整理,分类,抽象等诸多能力。
第三、推动能力。作为一个小组,一个团队会遇到很多的困难,当大家都在彷徨,变得消极的时候,你要积极的推动事情往前发展。
第四、决策能力。当路遇歧途的时候,你要勇于决策,这也意味着要勇于担当。

能武

要掌握一种过硬的技术,这个因人而定。能文不能武,让人觉得空谈,能武不能文,不能担当leader这样的角色。

概括起来,就是朝着做团队的leader方向发展,这也是大家更好的发挥自己的能力的一个方向,因为无论做什么事情都需要领导者,当仁不让,这个领导者就是你!

[转]PHP 编码规范

七月 27th, 2005 by admin

FROM : http://www.dualface.com/misc/docs/coding_standards.html

PHP 编码规范

原文:http://pear.php.net/manual/en/standards.php

翻译:廖宇雷

最后更新日期:2003/05/06

内容列表


缩进

缩进使用4个空格,而不是 tab。如果你使用 Emacs 编辑 PEAR 代码,你应该设置 indent-tabs-mode 为 nil。下面是一个 mode hook 的示例,用于设置 Emacs 符合缩进标准(你必须确保在编辑 PHP 文件时,这些设置发生作用):

(defun php-mode-hook ()
(setq tab-width 4
c-basic-offset 4
c-hanging-comment-ender-p nil
indent-tabs-mode
(not
(and (string-match "/(PEAR|pear)/" (buffer-file-name))
(string-match ".php$" (buffer-file-name))))))

这里是同等效果的 vim 规则:

set expandtab
set shiftwidth=4
set softtabstop=4
set tabstop=4


控制结构

控制结构包含 if、for、while、switch 等。这里有一个 if 语句的示例和一个 switch 语句的示例:

if 语句的示例:

<?php
if ((condition1) || (condition2)) {
action1;
} elseif ((condition3) && (condition4)) {
action2;
} else {
defaultaction;
}?>

switch 语句的示例:

<?php
switch (condition) {
case 1:
action1;
break;
case 2:
action2;
break;
default:
defaultaction;
break;
}
?>

控制语句应该在控制关键词和开始的圆括号之间应该有一个空格,以此和函数调用进行区别。

强烈建议你总是使用花括号将控制结构各部分标识出来。即使是在技术上可以不使用花括号的地方。这可以增加代码的可读性,同时避免在结构部分增加新行后引入逻辑上的错误。

原始代码:

if (condition)
return true;
else
return false;

修改后的代码:

if (condition)
do something; // 出现逻辑错误
return true;
else
return false;

正确的做法:

if (condition) {
do something;
return true;
} else {
return false;
}


函数调用

调用函数时,函数名和开始的括号之间不应该有空白字符。参数和开始及结束的括号之间不应有空格。而除第一个参数外,其他参数都应该用一个空格分隔。这里有一个示例:

<?php
$var = foo($bar, $baz, $quux);
?>

像上面的示例代码,赋值运算等号两边都应该使用一个空格。如果是相关的赋值运算,应该采用下面的形式以提供更好的可读性:

<?php
$short = foo($bar);
$long_variable = foo($baz);
?>


函数定义

按照“one true brace”约定声明函数:

<?php
function fooFunction($arg1, $arg2 = '')
{
if (condition) {
statement;
}
return $val;
}
?>

“one true brace”约定就是开始的花括号单独占一行,而不是跟在其他语句后面。

具有默认值的参数应该位于参数列表的后面(事实上 PHP 语言定义也要求如此)。如果适合,函数应该总是返回一个有意义的值。这里有一个稍微长一点的示例:

<?php
function connect(&$dsn, $persistent = false)
{
if (is_array($dsn)) {
$dsninfo = &$dsn;
} else {
$dsninfo = DB::parseDSN($dsn);
}

if (!$dsninfo || !$dsninfo['phptype']) {
return $this->raiseError();
}
return true;
}?>


注释

类型(class)的联机文档应该符合 PHPDoc(类似于 JavaDoc)的约定。更多关于 PHPDoc 的信息可以访问 http://www.phpdoc.de/ 获得。

此外,强烈鼓励使用非文档注释。一般性规则是对于那些容易忘记作用的代码添加简短的介绍性注释。

推荐使用 C 样式的注释(/* */)和标准 C++ 注释(//),而不应该使用 Perl/shell 样式的注释(#)。


包含代码

无论在什么地方无条件包含一个类型文件,应该使用 require_once()。如果有条件的包含一个类型文件(例如使用工厂方法),应该使用 include_once()。使用两者中的任何一个都能够确保类型文件只包含一次。它们共享一个文件列表,因此你不需要担心混淆他们 —— 一个文件使用 require_once() 包含后不会在 include_once() 中再一次被包含。

备注:include_once() 和 require_once() 是一个声明,而不是函数。你不需要使用圆括号将文件名扩起来(不过使用括号也不会出现错误)。


PHP 代码标记

总是使用 <?php ?> 来界定 PHP 代码,而不要使用 <? ?> 速记方式。这是为了符合 PEAR 一致性所必须的,同时也是在不同操作系统和不同安装设置环境下移植 PHP 代码所要求的。


头注释块

PEAR 发布的所有源代码文件头部都应该包含下面的注释块:

<?php
/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */
// +———————————————————————-+
// | PHP version 4 |
// +———————————————————————-+
// | Copyright (c) 1997-2002 The PHP Group |
// +———————————————————————-+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +———————————————————————-+
// | Authors: Original Author <author@example.com> |
// | Your Name <you@example.com> |
// +———————————————————————-+
//
// $ Id $
?>

这里没有硬性规定要将一个代码贡献者的名字添加到文件注释的作者列表中。一般情况下,他们的更改属于“substantial”目录(意味大约10%到20%的代码被改写)。有一个例外就是代码贡献者重写了函数或者贡献了新的程序逻辑。

简单的代码重组和 bug 修复不应该增加新作者,这是不恰当的。

不在核心 PEAR 仓库中的文件应该有一个类似的注释块来说明版权、许可协议和作者。所有文件应该包含一个模式行(modeline,用于 vim 和 emacs)以确保一致性。


使用 CVS

这个小节的内容仅仅适用于 cvs.php.net 上使用 CVS 的包。

在每一个文件中包含 $Id $(两个 $ 符号之间的关键字不能够有空格,但由于此文档也是用 CVS 管理,因此只好加个空格,避免被 CVS 替换掉) CVS 关键字,以便查看文件当前状态和最后修改时间等信息。如果已经存在“Last Modified:”这样的信息,则替换为 $Id $ 标记。

这个小节的其他内容假定你有关于 CVS 标记和分支(branches)的基本知识。

CVS 标记用于标识你包中的文件释放之前所作的修订。下面的列表是必需使用和建议使用的 CVS 标记:

RELEASE_n_n

(必需的)用于标记一个释放版本。如果你没有使用这个标记,别人就没有办法在你发布一个释放版本时从 CVS 服务器获取你的包。

QA_n_n

(分支,可选)如果你觉得在发布释放版本之前要提供一个候选释放版本,那么一个好主意就是增加一个分支。这个分支可以让你将释放版本隔离出来,并在正式发布释放版本之前可以为这些分支单独应用更新。期间,正常的开发工作可以在主干上继续进行。

MAINT_n_n

(分支,可选)如果你需要创建一个较小修改的释放版本(例如在 1.2 之后发布 1.2.1)。那么你可以创建一个分支来达到目的。

仅有 RELEASE 标记是必须的,其他标记为了方便推荐你使用。

下面是一个如何为 "Money_Fast" 包 1.2 释放版本增加标记的示例:

$ cd pear/Money_Fast
$ cvs tag RELEASE_1_2
T Fast.php
T README
T package.xml

经过上面的操作,就可以在 PEAR Web 网站上获取你的一系列释放版本了。

这里是一个如何建立 QA 分支的示例:

$ cvs tag QA_2_0_BP

$ cvs rtag -b -r QA_2_0_BP QA_2_0
$ cvs update -r QA_2_0
$ cvs tag RELEASE_2_0RC1
…and then the actual release, from the same branch:
$ cvs tag RELEASE_2_0

"QA_2_0_BP" 标记是一个 "branch point" 标记,用于标记分支的开始。总是用这样的标记来标明分支的开始是一个好主意。MAINT 分支可以使用 RELEASE 标记作为它的分支起点。


示例中的 URL

所有示例中用到的 URL 地址都应该是 "example.com"、"example.org"、"example.net"。


命名约定

一般而言,class、函数和变量的名字应该总是能够描述让代码阅读者能够容易的知道这些代码的作用。

Classes

class 应该具有一个描述性的名字。可能时应该避免使用缩写。class 名字应该总是用一个大写字母开始。从 class 名字中也能够反映出 PEAR class 的层次。层次中的每个级别都用下划线进行分隔。好的 class 名字示例如下:

Log
Net_Finger
HTML_Upload_Error

函数和方法

函数和方法应该使用 "studly caps" 样式命名。函数应该将所在包的名字作为前缀,以避免与其他包的函数发生名字冲突。名字的受字母(前缀之后)应该是小写,每一个新单词应该以大写字母开头。下面是一些示例:

connect()
getData()
buildSomeWidget()
XML_RPC_serializeData()

私有 class 成员和属性(意味着 class 成员和属性只应该由同一个 class 中声明的成员使用。不过 PHP 并不支持强制性的私有命名空间)应该用一个下划线开头。示例:

_sort()
_initTree()
$this->_status

常数

常数应该总是全部使用大写字母命名,用下划线来分隔单词。常数名字的前缀应该使用大写的 class/包 名字。例如:DB:: 包使用的所有常数都已 DB_ 开头。

全局变量

如果你的包需要定义全局变量,那么应该用下划线跟上包的名字和另一个下划线作为开头。例如,PEAR 包使用一个全局变量名为 $_PEAR_destructor_object_list。

预定义的值 true、false 和 null

PHP 的内建值 true、false 和 null 必须全部用小写字母书写。

[转]创造世界上最简单的 PHP 开发模式

七月 27th, 2005 by admin

xLight乱评:感觉这个模式并适合 大型项目开发,小项目按这个流程走是不错的选择。

最近想学CASE ,不知道有没有人能给我提供点资料阿?

创造世界上最简单的 PHP 开发模式
作者:大龄青年

本文链接:
http://www.openphp.cn/index.php/article/2/30/index.html

/*************************************/
/* author:大龄青年
/* email :wenadmin@sina.com
/* from:
http://blog.csdn.net/hahawen
/*************************************/

  php 作为“最简单”的 Web 脚本语言, 在国内的市场越来越大,phper 越来越多,但是感觉大多数人好像没有考虑到模式问题,什么样的设计模式才是最优的,才是最适合自己目前工作的,毕竟效率是最重要的(用省下的时间打游戏,多美啊…)。MVC 应该是首选,www.sourceforge.net 上有好多优秀的基于 MVC 的开源项目,大家可以冲过去研究研究。

  前几天给自己公司网站改版,主要还是文章发布系统,老板说后台我想怎么设计就怎么设计,唯一的前提就是快。于是自己搭建了一个简单的发布系统的框架。如果单纯从文章发布系统上讲,基本上可以满足“中小型”企业网站的文章发布系统的要求,后台的总共的php代码不超过800行,而且支持任意扩充和plugin功能。

  废话不再说了,下面把我的架构讲一下,希望对您能有所帮助。

  注意:在开始前,需要您下载一个模板处理工具类:“smarttemplate”,并了解一些模板的简单的使用。

  我的测试环境:windows2k/apache2/php4.3.2/smarttemplate类库

  先讲一下整个web站点的文件的分布,在后面的章节中将陆续创建并填充下面的目录和文件
  我的服务器的web的根目录是 “C:/Apache2/htdocs/”
  我在下面建立了一个文件夹“cmstest”作为我的网站的主文件夹
  文件夹“cmstest”下面的子文件结构是:

/config.inc.php
/list1.php
/list2.php
/new.php
/add.php
/view.php
/page.js
/src/MysqlUtil.php
/src/ArticleUtil.php
/src/CoreUtil.php
/src/ParseTpl.php
/src/lib/smarttemplate/*.* 这个目录用来存放smarttemplate的类库的
/smart/template/list1.htm
/smart/template/list2.htm
/smart/template/new.htm
/smart/template/add.htm
/smart/template/view.htm
/smart/cache/
/smart/temp/

设计步骤:

  1. 考虑自己公司的网站的特点和已经设计的模板的结构,总结要实现的功能,列出清单。
  2. 分析功能清单,把功能分类。每一类的功能都是有共同点的,可以通过相同的方法实现的。
  3. 根据功能,设计数据库的表结构
  4. 设计一个配置文件config.inc.php, 用来记录网站的一些基本的信息,包括数据库名……..
  5. 为每一类功能设计数据库查询的接口函数,这样以后相似的操作只要调用这个接口就可以了。这样避免了以后可能发生的大量的代码重复的操作,也就达到了代码复用的目的。
  6. 定义自己对模板工具的包装函数,以后调用的时候就不用管模板工具的使用问题了,只有往自己的包装函数里面塞数就可以了。
  7. 基础函数已经ok了,开始轻松的页面实现和模板的处理了。

  我们现在就开始设计一个简单的系统,看看我是怎么一步一步地实现一个“最简单的文章的发布系统”的,当然只是我模拟的一个简单的项目,实际中一个项目可能比这要复杂的多。

一、分析我的案例:

呵呵,这个客户项目好简单的啊,幸福ing……….

list1.php:有三个文章列表和一个按钮,“php开发文章列表”“php开发热点文章列表”“asp开发最新文章”“添加新文章”
list2.php:有2个文章列表“asp开发文章列表”“asp开发热点文章列表”
new.php:一个添加文章的表单的页面
add.php: 处理new.php的表单的页面
view.php: 文章察看的页面

二、分析功能

“php开发文章列表”“asp开发文章列表”——-按文章的发布顺序,倒序排列显示,每页显示5篇文章
“php开发热点文章列表”“asp开发热点文章列表”——-按文章的点击察看次数排序显示文章,显示3篇文章
“asp开发最新文章”按文章的发布顺序,倒序排列显示,显示3篇文章
“添加新文章”——一个文章的发布功能, 包括文章标题/作者/内容
“文章察看”———显示某篇文章内容

综合的看一下,对功能进行分类包括:
1、文章列表:正常的分页列表、按点击数列表、按发布顺序的列表
2、文章发布:一个表单的输入和处理
3、文章察看:读取显示文章内容

呵呵,功能的确是太简单了些。

三、设计数据库:

数据库名:cmstest

数据表:

CREATE TABLE `article` (
`id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR( 100 ) NOT NULL ,
`content` TEXT NOT NULL ,
`datetime` DATETIME NOT NULL ,
`clicks` INT( 11 ) ,
`pid` TINYINT( 2 ) NOT NULL ,
PRIMARY KEY ( `id` )
);

CREATE TABLE `cat` (
`cid` TINYINT( 2 ) NOT NULL ,
`cname` VARCHAR( 20 ) NOT NULL ,
PRIMARY KEY ( `cid` )
);

——————————
article表是文章内容表,
—————————-
`id` 文章编号
`title` 文章标题
`content` 文章内容
`datetime` 发布时间
`clicks` 点击数
`pid` 分类表号
——————————
cat表是文章的类别表
—————————-
`cid` 分类表号
`cname` 分类名称
—————————-

上面是表的数据库结构,光有了这些还不够,还要有数据
INSERT INTO `cat` VALUES(1, "php开发"),(2, "asp开发");
INSERT INTO `article` VALUES(1, "php开发1", "php开发1内容", "2004-8-1 1:1:1", 0, 1);
INSERT INTO `article` VALUES(2, "php开发2", "php开发2内容", "2004-8-2 1:1:1", 0, 1);
INSERT INTO `article` VALUES(3, "php开发3", "php开发3内容", "2004-8-3 1:1:1", 4, 1);
INSERT INTO `article` VALUES(4, "php开发4", "php开发4内容", "2004-8-4 1:1:1", 3, 1);
INSERT INTO `article` VALUES(5, "php开发5", "php开发5内容", "2004-8-5 1:1:1", 2, 1);
INSERT INTO `article` VALUES(6, "php开发6", "php开发6内容", "2004-8-6 1:1:1", 1, 1);
INSERT INTO `article` VALUES(7, "php开发7", "php开发7内容", "2004-8-7 1:1:1", 0, 1);
INSERT INTO `article` VALUES(8, "jsp开发1", "jsp开发1内容", "2004-8-1 1:1:1", 0, 2);
INSERT INTO `article` VALUES(9, "jsp开发2", "jsp开发2内容", "2004-8-2 1:1:1", 0, 2);
INSERT INTO `article` VALUES(10, "jsp开发3", "jsp开发3内容", "2004-8-3 1:1:1", 4, 2);
INSERT INTO `article` VALUES(11, "jsp开发4", "jsp开发4内容", "2004-8-4 1:1:1", 3, 2);
INSERT INTO `article` VALUES(12, "jsp开发5", "jsp开发5内容", "2004-8-5 1:1:1", 2, 2);
INSERT INTO `article` VALUES(13, "jsp开发6", "jsp开发6内容", "2004-8-6 1:1:1", 1, 2);
INSERT INTO `article` VALUES(14, "jsp开发7", "jsp开发7内容", "2004-8-7 1:1:1", 0, 2);

这样我们的数据库就设计完了。接下来就开始涉及到具体的实现了。

四、设计config.inc.php文件

这个文件用来设置一些web上通用的数据信息和一些参数,其他的具体的实现页面都通过这个页面获取需要的数据,下面是配置的清单

<?php
//数据库设置 define('DB_USERNAME', 'root'); define('DB_PASSWORD', ''); define('DB_HOST', 'localhost'); define('DB_NAME', 'cmstest'); define('DB_PCONNECT', true);
// web的基本路经设置 define('CMS_ROOT', 'C:/Apache2/htdocs/cmstest/'); define('CMS_SRCPATH', CMS_ROOT.'src/');
//smarttemplate 模板解析工具的设置 define('SMART_REUSE_CODE', false); define('SMART_TEMPLATE_DIR', CMS_ROOT.'smart/template/'); define('SMART_TEMP_DIR', CMS_ROOT.'smart/temp/'); define('SMART_CACHE_DIR', CMS_ROOT.'smart/cache/'); define('SMART_CACHE_LIFETIME', 100);
require_once(
CMS_SRCPATH . 'lib/smarttemplate/class.smarttemplate.php'
);
//要包含的基础文件,里面都是一些基本的函数 require_once CMS_SRCPATH.'MysqlUtil.php';
require_once
CMS_SRCPATH.'ArticleUtil.php'
;
require_once
CMS_SRCPATH.'CoreUtil.php'
;
require_once
CMS_SRCPATH.'ParseTpl.php'
;
//session 控制 session_cache_limiter('private_no_expire'); session_start();
?>

  其中的 define('CMS_ROOT', 'C:/Apache2/htdocs/cmstest/'); 路经根据自己apach的web路经来改(参照最开始介绍文件夹结构的地方改)。

五、制作功能接口(1)

  首先对 mysql 数据库函数进行包装,简化对数据库操作,网上有很多这样的开源的类。但是这里我个人根据自己的需求和习惯,自己对 mysql 的函数进行了包装,写得好坏就先不管了。这个地方简单的看一下就可以了,不同的包装的类操作是不同的,而且这里的主要目的是理解这套“架构”,不用太扣代码。

——-MysqlUtil.php——–
<?php
function dbConnect
(){
global
$cnn
;
$cnn = (DB_PCONNECT? mysql_pconnect(DB_HOST, DB_NAME, DB_PASSWORD
):
mysql_connect(DB_HOST, DB_NAME, DB_PASSWORD
)) or
die(
'数据库连接错误'
);
mysql_select_db(DB_NAME, $cnn) or die('数据库选择错误'
);
mysql_query("SET AUTOCOMMIT=1"
);
}

function &dbQuery($sql){
global
$cnn
;
$rs = &mysql_query($sql, $cnn
);
while(
$item=mysql_fetch_assoc($rs
)){
$data[] = $item
;
}
return
$data
;
}

function &dbGetRow($sql){
global
$cnn
;
$rs = mysql_query($sql) or die('sql语句执行错误'
);
if(
mysql_num_rows($rs)>0
)
return
mysql_fetch_assoc($rs
);
else
return
null
;
}

function dbGetOne($sql, $fildName){
$rs = dbGetRow($sql
);
return
sizeof($rs)==null? null: (isset($rs[$fildName])? $rs[$fildName]: null
);
}

function &dbPageQuery($sql, $page=1, $pageSize=20){
if(
$page===null) return dbQuery($sql
);
$countSql = preg_replace('|SELECT.*FROM|i','SELECT COUNT(*) count FROM', $sql
);
$n = (int)dbGetOne($countSql, 'count'
);
$data['pageSize'] = (int)$pageSize<1? 20: (int)$pageSize
;
$data['recordCount'] = $n
;
$data['pageCount'] = ceil($data['recordCount']/$data['pageSize'
]);
$data['page'] = $data['pageCount']==0? 0: ((int)$page<1? 1: (int)$page
);
$data['page'] = $data['page']>$data['pageCount']? $data['pageCount']:$data['page'
];
$data['isFirst'] = $data['page']>1? false: true
;
$data['isLast'] = $data['page']<$data['pageCount']? false: true
;
$data['start'] = ($data['page']==0)? 0: ($data['page']-1)*$data['pageSize']+1
;
$data['end'] = ($data['start']+$data['pageSize']-1
);
$data['end'] = $data['end']>$data['recordCount']? $data['recordCount']: $data['end'
];
$data['sql'] = $sql.' LIMIT '.($data['start']-1).','.$data['pageSize'
];
$data['data'] = &dbQuery($data['sql'
]);
return
$data
;
}

function dbExecute($sql){
global
$cnn
;
mysql_query($sql, $cnn) or die('sql语句执行错误'
);
return
mysql_affected_rows($cnn
);
}

function dbDisconnect(){
global
$cnn
;
mysql_close($cnn
);
}

function sqlGetOneById($table, $field, $id){
return
"SELECT * FROM $table WHERE $field=$id"
;
}

function sqlMakeInsert($table, $data){
$t1 = $t2
= array();
foreach(
$data as $key=>$value
){
$t1[] = $key
;
$t2[] = "'".addslashes($value)."'"
;
}
return
"INSERT INTO $table (".implode(",",$t1).") VALUES(".implode(",",$t2).")"
;
}

function sqlMakeUpdateById($table, $field, $id, $data){
$t1
= array();
foreach(
$data as $key=>$value
){
$t1[] = "$key='".addslashes($value)."'"
;
}
return
"UPDATE $table SET ".implode(",", $t1)." WHERE $field=$id"
;
}

function sqlMakeDelById($table, $field, $id){
return
"DELETE FROM $table WHERE $field=$id"
;
}
?>

五、制作功能接口(2)

下面来正式的看看,我们共要实现的功能进行的包装

————ArticleUtil.php—————-
<?php //显示文章列表的函数
//getArticleList(文章类别, 排序方法, 当前显示第几页, 每页显示几条)
function getArticleList($catId, $order, $page, $pageSize
){
$sql = "SELECT * FROM article WHERE pid=$catId ORDER BY $order"
;
return
dbPageQuery($sql, $page, $pageSize
);
}
//查询某个文章的内容
//getArticle(文章编号)
function getArticle($id
){
$sqlUpdate = "UPDATE article SET clicks=clicks+1 WHERE id=$id"
;
dbExecute($sqlUpdate
);
$sql = "SELECT * FROM article WHERE art_id=$id"
;
return
dbGetRow($sql
);
}
//添加文章
//addArticle(文章内容数组)
function addArticle($data
){
$sql = sqlMakeInsert('article', $data
);
return
dbExecute($sql
);
}
?>

这段代码是不是就简单多了啊?这就是自己对mysql函数进行包装的好处!
下面来研究一下他们是怎么实现我们的功能的呢。
“php开发文章列表”——–getArticleList(1, "id DESC", $page, 5)
“asp开发文章列表”——–getArticleList(2, "id DESC", $page, 5)
“php开发热点文章列表”—-getArticleList(1, "clicks DESC, id DESC", 1, 3)
“asp开发热点文章列表”—-getArticleList(2, "clicks DESC, id DESC", 1, 3)
“asp开发最新文章”——–getArticleList(2, "id DESC", 1, 3)
“添加新文章”————-addArticle($data)
“察看文章”—————getArticle($id)

六、对smarttemplate类进行包装(革命尚未成功,同志仍须努力)

具体的smarttemplate的使用这里就不讲了,不然口水讲没了,都讲不完。下面这个是具体的对包装函数

————-ParseTpl.php—————-
<?php
function renderTpl($viewFile, $data
){
$page = new SmartTemplate($viewFile
);
foreach(
$data as $key=>$value
){
if(isset(
$value[data
])){
$page->assign($key, $value[data
]);
unset(
$value[data
]);
$page->assign($key."_page", $value
);
} else {
$page->assign($key, $value
);
}
}
$page->output
();
}
?>

七:文章列表察看页面实现和模板处理(万里长征的最后一步)

先来看看页面list1的实现,在list1里面分页用了一个page.js文件,这个文件是自己给自己写的一个js分页的函数,挺好用的
—————page.js—————

//——–共 20 条记录,当前 86/99 页 [1]… [82] [83] [84] [85] [86] [87] [88] [89] [90] …[99] GO——————-
//recordCount = 20;
//show = 20
//pageShow = 11;
//pageCount = 100;
//pageNow = 86;
//pageStr = "?page=_page_";
//document.write(showListPage(recordCount, show, pageCount, pageNow, pageStr));
function showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr){
if(pageCount<1) pageCount =0;
if(pageNow<1) pageNow = 0;
str = '共 <B>'+recordCount+'</B> 条记录,当前 <B>'+pageNow+'/'+pageCount+'</B> 页 ';

if(pageCount<=pageShow){
startHave = false;
endHave = false;
startNum = 1;
endNum = pageCount;
} else if(pageNow-1 <= pageShow/2){
startHave = false;
endHave = true;
startNum = 1;
endNum = pageShow-1;
} else if(pageCount-pageNow <= pageShow/2){
startHave = true;
endHave = false;
startNum = pageCount - pageShow + 2;
endNum = pageCount;
} else {
startHave = true;
endHave = true;
startNum = pageNow - Math.floor((pageShow-2)/2);
endNum = startNum + pageShow - 3;
}

if(startHave){
startStr = " [<A href='"+pageStr.replace("_page_",1)+"'>1</A>]… ";
str += startStr;
}

for(i=startNum; i<=endNum; i++){
if(pageNow==i)
str += "[" + i + "]";
else
str += " [<A href='" + pageStr.replace("_page_",i) + "'>" + i + "</A>] ";
}

if(endHave){
endStr = " …[<A href='" + pageStr.replace("_page_",pageCount) + "'>" + pageCount + "</A>] ";
str += endStr;
}
return str;
}
————–list1.htm—————-
<a href="new.php">添加新文章</a><hr>
<table>
<tr><th>php开发文章</th></tr>
<!– BEGIN phplist –>
<tr><td>{id}–<a href="view.php?id={id}">{title}</a></td></tr>
<!– END phplist –>
</table>
<!– BEGIN phplist_page –>
<script src="page.js" language="javascript"></script>
<script language="javascript">
recordCount = {recordCount}; //总记录数
show = {pageSize}; //每页显示的记录数量
pageShow = 10; //每页显示的分页连接数量
pageCount = {pageCount}; //总页数
pageNow = {page}; //当前页数
pageStr = "?page=_page_"; //页面连接
document.write(showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr));
</script>
<!– END phplist_page –>
<hr>
<table ID="Table1">
<tr><th>php开发热点文章</th></tr>
<!– BEGIN phphotlist –>
<tr><td>{id}–<a href="view.php?id={id}">{title}</a></td></tr>
<!– END phphotlist –>
</table><hr>
<table ID="Table2">
<tr><th>asp开发最新文章</th></tr>
<!– BEGIN aspnewlist –>
<tr><td>{id}–<a href="view.php?id={id}">{title}</a></td></tr>
<!– END aspnewlist –>
</table>

————–list1.php—————-
<?php
require_once "config.inc.php"
;
dbConnect
(); $data = array(); $data[phplist] = getArticleList(1, "id DESC", (int)$_GET[page], 5); $data[phphotlist] = getArticleList(1, "clicks DESC, id DESC", 1, 3); $data[aspnewlist] = getArticleList(2, "id DESC", 1, 3); dbDisconnect();
renderTpl('list1.htm', $data
);
?>

运行的效果怎么样,是不是实现了要求的功能呢。现在我们再做一下改动,在里面加上“asp开发热点文章列表”,实现代码如下

————–list1.htm—————-
<a href="new.php">添加新文章</a><hr>
<table>
<tr><th>php开发文章</th></tr>
<!– BEGIN phplist –>
<tr><td>{id}–<a href="view.php?id={id}">{title}</a></td></tr>
<!– END phplist –>
</table>
<!– BEGIN phplist_page –>
<script src="page.js" language="javascript"></script>
<script language="javascript">
recordCount = {recordCount}; //总记录数
show = {pageSize}; //每页显示的记录数量
pageShow = 10; //每页显示的分页连接数量
pageCount = {pageCount}; //总页数
pageNow = {page}; //当前页数
pageStr = "?page=_page_"; //页面连接
document.write(showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr));
</script>
<!– END phplist_page –>
<hr>
<table ID="Table1">
<tr><th>php开发热点文章</th></tr>
<!– BEGIN phphotlist –>
<tr><td>{id}–<a href="view.php?id={id}">{title}</a></td></tr>
<!– END phphotlist –>
</table><hr>
<table ID="Table2">
<tr><th>asp开发最新文章</th></tr>
<!– BEGIN aspnewlist –>
<tr><td>{id}–<a href="view.php?id={id}">{title}</a></td></tr>
<!– END aspnewlist –>
</table>
<table ID="Table3">
<tr><th>asp热点文章</th></tr>
<!– BEGIN asphotlist –>
<tr><td>{id}–<a href="view.php?id={id}">{title}</a></td></tr>
<!– END asphotlist –>
</table>

————–list1.php—————-
<?php
require_once "config.inc.php"
;
dbConnect
(); $data = array(); $data[phplist] = getArticleList(1, "id DESC", (int)$_GET[page], 5); $data[phphotlist] = getArticleList(1, "clicks DESC, id DESC", 1, 3); $data[aspnewlist] = getArticleList(2, "id DESC", 1, 3); $data[asphotlist] = getArticleList(2, "clicks DESC, id DESC", 1, 3); dbDisconnect();
renderTpl('list1.htm', $data
);
?>

  仔细观察一下前后的区别,list1.php里面只是简单的加入了一行的代码,就实现这个改动,感觉怎么样啊?是不是超级简单。

其实这种设计模式的好处还不只是这点:
1、可以把程序的核心代码隔离开管理,便于以后程序的管理维护
2、对于程序的可扩展性也很好,假设list1.php中要加入产品列表,我是不是也可以这么做呢?把对产品的管理也写成统一的数据库操作接口,然后简单的修改模板文件加入产品列表部分,最后在list1.php中加入一行函数调用的代码,就可以实现。
3、代码复用,如果您是做中小型企业网站的,那这么做对您的好处是最大的,因为这种类型的网站的设计结构几乎是一样的,您可能只需要更改一下模板的样式,就可以赚到钞票了。

  这么看来这种模式是不是给您带来了很多的好处呢?

———–lsit2.htm—————
<a href="new.php">添加新文章</a><hr>
<table ID="Table1">
<tr><th>asp开发文章</th></tr>
<!– BEGIN asplist –>
<tr><td>{id}–<a href="view.php?id={id}">{title}</a></td></tr>
<!– END asplist –>
</table>
<!– BEGIN asplist_page –>
<script src="page.js" language="javascript"></script>
<script language="javascript">
recordCount = {recordCount}; //总记录数
show = {pageSize}; //每页显示的记录数量
pageShow = 10; //每页显示的分页连接数量
pageCount = {pageCount}; //总页数
pageNow = {page}; //当前页数
pageStr = "?page=_page_"; //页面连接
document.write(showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr));
</script>
<!– END asplist_page –>
<hr>
<table ID="Table4">
<tr><th>asp热点文章</th></tr>
<!– BEGIN asphotlist –>
<tr><td>{id}–<a href="view.php?id={id}">{title}</a></td></tr>
<!– END asphotlist –>
</table>

———–lsit2.php—————
<?php
require_once "config.inc.php"
;
dbConnect
(); $data = array(); $data[asplist] = getArticleList(2, "id DESC", (int)$_GET[page], 5); $data[asphotlist] = getArticleList(2, "clicks DESC, id DESC", 1, 3); dbDisconnect();
renderTpl('list2.htm', $data
);
?>
——–view.htm————–
<!– BEGIN content –>
编号:{id}<br>标题:{title}<br>内容:{content}
<!– END content –>

——–view.php——————
<?php
require_once "config.inc.php"
;
dbConnect
(); $data = array(); $data[content] = getArticle((int)$_GET[id]); dbDisconnect();
renderTpl('view.htm', $data
);
?>

八:文章添加实现和模板处理(万里长征的再来一步)

—————new.htm———–
<form action="add.php" method="post">
标题:<input type="text" size="20"><br>
内容:<textarea cols="50" rows="4"></textarea><br>
&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="提交">
</form>

—————new.php————
<?php
require_once "config.inc.php"
;
renderTpl('new.htm'
, array());
?>

—————CoreUtil.php————–
<?php
function doPo