Submitted by gouki on 2008, November 18, 5:52 PM
转载自中文网站管理员博客
跟网络管理员沟通时经常会出现这种情形,一些广为传播的理念可能在过去是正确的,但是可能已不再切合目前的情况了。当我们最近在跟几个朋友谈及关于网址的结构时就碰到这种情况。其中一个朋友很担心动态网址的使用,甚至认为“搜索引擎无法处理动态网址”。另外一个朋友觉得动态网址对搜索引擎来说完全不是问 题,那些都是过去的事了。还有一个甚至说他从来都搞不懂动态网址和静态网址相比有什么区别。对于我们来说,这一刻使我们决定要好好研究一下动态网址和静态 网址这个话题。首先,让我们来界定一下我们要谈论的主题:
什么是静态网址?
一个静态网址,顾名思义,就是一个不会发生变化的网址,它通常不包含任何网址参数。例如:http://www.example.com/archive/january.htm。您可以在搜索框里输入 filetype:html 在谷歌上搜索静态网址。更新此种类型网址的页面会比较耗费时间,尤其是当信息量增长很快时,因为每一个单独的页面都必须更改编译代码。这也是为什么网站管理员们在处理大型的、经常更新的网站,像在线购物网站、论坛社区、博客或者是内容管理系统时,会使用动态网址的原因。
什么是动态网址?
如果一个网站的内容存储于一个数据库,并且根据要求来显示页面,这时就可以使用动态网址。在这种情况下,网站提供的内容基本上是基于模板形式的。通常情况下,一个动态网址看起来像这样:http://code.google.com/p/google-checkout-php-sample-code/issues/detail?id=31。 您可以通过寻找像? = & 这样的符号识别出动态网址。动态网址有一个缺陷是不同的网址可以拥有相同的内容。这样导致不同的用户可能链向含有不同参数的网址,但是这些网址却都含有相 同的内容。这也是为什么网络管理员有时候想要将这些动态网址重写成静态网址的原因之一。
我是不是应该让我的动态网址看起来是静态的呢?
在处理动态网址时,希望您能了解以下几点事实:
- 要正确地生成和维护从动态网址到静态化网址的重写转变实际上是一件很难的事情。
- 将原始的动态网址提供给我们会比较安全,请让我们来处理诸如探测和避开那些有问题的参数的事情。
- 如果您想重写网址,请去掉那些不必要的参数,同时请保持它动态网址的样子。
- 如果您想提供一个静态网址代替动态网址,那么您应该切实地生成相应的静态内容。
静态和动态网址,Googlebot对于哪一个识别得更好呢?
我 们碰到过很多网站管理员,像我们的朋友那样,认为静态或者看起来是静态的网址对于网站的索引和排名是有优势的。这种看法是基于这样一个假设,即认为搜索引 擎在抓取和分析含有会话标识(session ID)和来源追踪器(source tracker)的网址时是有问题的。然而,事实是,谷歌在这两个方面都有了相当的进展。就点击率来说,静态网址可能略微有些优势,因为用户可以很容易地 读懂这个网址。但是,就索引和排名来说,使用数据库驱动网站并不意味着明显的劣势。相比较将参数隐藏以使他们看起来是静态的网址来说,我们更希望网站将动 态的网址直接提供给搜索引擎。
现在,让我们来看一些有关动态网址的广为传播的看法,并且来纠正一些蒙蔽网站管理员的假说。:)
传说:“动态网址不能被抓取。”
事实:我们可以抓取动态网址并且解释不同的参数。如果您为了让网址看起来像是静态的,而隐藏那些可以给谷歌提供有价值信息的参数,这样做反而会给该网址的抓取和排名带来麻烦。我们的建议是:请不要将一个动态网址改换格式以使其看起来是静态的。尽可能地使用静态网址来显示静态内容是可取的,但在您决定展示动态内容的情况下,请不要将参数隐藏起来从而使他们看起来像是静态的,因为这样做会删除掉那些有助于我们分析网址的有用信息。
传说:“动态网址的参数要少于3个。”
事实:对于参数的数量是没有限制的。但是,一个好的经验是不要让您的网址太长(这 个适用于所有的网址,不论是静态的还是动态的)。您可以去掉一些对于Googlebot来说不重要的参数,给用户一个好看一点的动态网址。如果您不能确定 可以去掉哪些参数,我们建议您将动态网址中所有的参数都提供给我们,我们的系统会弄明白哪一些是不重要的。将参数隐藏起来会影响我们正确地分析您的网址, 我们也就不能识别这些参数,一些重要信息可能也因此丢失了。
下面一些是我们认为您可能会存在疑问的一些问题。
这是否意味着我应该完全避免重写动态网址?
这 是我们的建议,除非您能确保您只是去掉多余的参数,或能够把所有有可能有不良影响的参数完整地删除。如果您把自己的动态网址任意修改使其看起来像是静态 的,您要清楚这样做是有风险的,有可能会导致有些信息不能被正常地编译和识别。如果您想给您的网站再增加一个静态的版本,请您一定要提供一个真正意义上的 静态的内容,比如生成那些可以通过网站相应路径而获取的文件。如果您仅仅是修改了动态网址的表现形式,而没有真正提供静态的内容,那么您有可能适得其反。 请直接把标准的动态URL提供给我们,我们会自动找出那些冗余的参数。
你能给我举一个例子么?
如 果您有一个像下面这样标准格式的动态网址:foo?key1=value&key2=value2,我们建议您不用改动它,谷歌会决定哪些参数可 以去掉;或者您可以为用户去掉那些不必要的参数。不过要慎重,仅仅去掉那些不重要的参数。这里有一个含有多个参数的动态网址的例子:
www.example.com/article/bin/answer.foo?language=en&answer=3&sid=98971298178906&query=URL
- language=en – 标明这篇文章的语言
- answer=3 – 这篇文章含有数字3
- sid=8971298178906 – 会话标识代码是8971298178906
- query=URL – 使这篇文章被找到的查询是[URL]
并不是所有的参数都提供额外的信息。所以将这个网址重写为www.example.com/article/bin/answer.foo?language=en&answer=3 可能不会引起任何问题,因为所有不相关的参数都去掉了。
下面是一些经过认为修改而看起来像是静态网址的例子。相比较没有重写、直接提供动态网址来说,这些网址可能会引起更多抓取方面的问题。
- www.example.com/article/bin/answer.foo/en/3/98971298178906/URL
- www.example.com/article/bin/answer.foo/language=en/answer=3/ sid=98971298178906/query=URL
- www.example.com/article/bin/answer.foo/language/en/answer/3/sid/ 98971298178906/query/URL
- www.example.com/article/bin/answer.foo/en,3,98971298178906,URL
如 果您将动态网址重写成如上所述的示例的话,可能会导致我们很多不必要的抓取,因为这些网址中都含有会话标识(sid)和查询(query)参数的可变值, 这无形中生成了很多看起来不同的URL,而他们包含的内容却是相同的。这些格式让我们很难理解通过这个网址返回的实际内容和参数URL以及 98971298178906是无关的。不过,下面这个重写的例子却将所有无关的参数都去掉了:
- www.example.com/article/bin/answer.foo/en/3
尽 管我们可以正确地处理这个网址,我们还是不鼓励您使用这样的重写。因为它很难维护,而且一旦一个新的参数被加到原始的动态网址,那么这个网址就需要马上更 新。不这样做的话就会再次导致生成一个隐藏了参数的貌似静态网址的URL。所以最好的解决方法是通常将动态网址保持他们原来的样子。或者,如果您去掉不相 关的参数,请记住一定要保持这个网址是动态的:
- www.example.com/article/bin/answer.foo?language=en&answer=3
本文来自:http://adsense.googlechinablog.com/2008/11/blog-post_18.html
Tags: google, seo, 统计, 优化, 更新
Misc | 评论:0
| 阅读:22507
Submitted by gouki on 2008, November 16, 8:48 PM
经过一个多月的开发,最新版本的Ubuntu Tweak正式发布了。 Ubuntu Tweak 0.4.2修正并改善了许多方面,并引入了“源编辑器”这个新特性。 —- 为了方便用户更方法的编辑和设定源,Ubuntu Tweak 0.4.2版加入了“源编辑器”。 什么是“源编辑器”呢?我来通过下面几张图片来展示它的相关功能。
基本功能:方便编辑源
首先,“源编辑器”提供一个巨大的文本框来让用户方便地编辑源。
只要点击“应用程序”->“源编辑器”,并解锁后,就可以马上可以开始自由地编辑源了。这个编辑区域支持语法高亮,使源更容易辨认。
通过这个,用户不再需要打开终端,执行:sudo gedit /etc/apt/sources.list等命令。
编辑完毕,保存后,可以点击“刷新”立即更新系统。
更新为预设的源
首次安装,或重装了Ubuntu后第一件事情就是要更改源。
现在通过Ubuntu Tweak来简单地完成这些吧!点击“更新源”,Ubuntu Tweak将会从网上更新下来一些常用、好用的源,根据自己的网络环境,确定并保存以后,就可以完成源的更改并马上更新系统了。
没有打开浏览器查询,没有打开终端的过程,没有复制和粘贴,一切用Ubuntu Tweak为你搞定!
上传新鲜的源
如果有更好的源了,但是服务器上没有收录,你就可以尝试将其上传。首先保证你使用了该用,然后点击“提交源”,简单地填上标题和相关注释,就可以上传了。
当然上传后的结果将经过审核才会开放出给他人使用,如果你有什么好的源而且默认的列表没有收录的话,赶快提交并与大家一块分享吧!
增加第三方源
这个版本继续完善了第三方源,加入了OpenOffice 3.0、Amarok等第三方源。其中还为特别为中文用户加入了Ubuntu中文源。
中文用户只要启用这个源,就可以立马享受到免费的永中Office2009,Ubuntu Tweak和好用的iBus输入法等好东西!
确保启用了中文源,你就可以在“添加/删除”中方便地安装“永中Office 2009 个人版”和iBus输入了!
除了以上新鲜玩意,Ubuntu Tweak 0.4.2还改善并修正了一些Bug,并重新制定了压缩包依赖,这样使用8.04以前的Ubuntu用户也能再次使用Ubuntu Tweak了。
还等什么,下载或从源里更新吧!
源代码:
ubuntu-tweak_0.4.2.orig.tar.gz
Deb包:
ubuntu-tweak_0.4.2-1~intrepid1_all.deb
消息来源:Linux桌面中文网
Tags: linux, ubuntu, tweak, 源编辑器
Software | 评论:0
| 阅读:23336
Submitted by gouki on 2008, November 17, 9:12 AM
PHP函数库里面,提到CURL,恐怕很多人都会翘起大拇指吧,确实,这个函数库太牛叉了
CURL其实是调用的CURL的lib,随着PHP版本的升高,curl所需的lib版本也随之提高。
关于CURL所必须的类库和安装说明,手册上有详细介绍:
XML/HTML代码
- Requirements
-
- In order to use PHP's cURL functions you need to install the libcurl package. PHP requires that you use libcurl 7.0.2-beta or higher. In PHP 4.2.3, you will need libcurl version 7.9.0 or higher. From PHP 4.3.0, you will need a libcurl version that's 7.9.8 or higher. PHP 5.0.0 requires a libcurl version 7.10.5 or greater.
-
- Installation
-
- To use PHP's cURL support you must also compile PHP --with-curl[=DIR] where DIR is the location of the directory containing the lib and include directories. In the "include" directory there should be a folder named "curl" which should contain the easy.h and curl.h files. There should be a file named libcurl.a located in the "lib" directory. Beginning with PHP 4.3.0 you can configure PHP to use cURL for URL streams --with-curlwrappers.
-
- Note to Win32 Users: In order to enable this module on a Windows environment, libeay32.dll and ssleay32.dll must be present in your PATH.
- You don't need libcurl.dll from the cURL site.
然后在使用的时候也很方便,只需要初始化一下,设置一下postfields或者GET啥啥的,最后exec一下就行了。关键是别忘了close.
例子代码如下:
PHP代码
- $ch = curl_init("http://www.example.com/");
- $fp = fopen("example_homepage.txt", "w");
-
- curl_setopt($ch, CURLOPT_FILE, $fp);
- curl_setopt($ch, CURLOPT_HEADER, 0);
-
- curl_exec($ch);
- curl_close($ch);
- fclose($fp);
以上例子代码有点特殊,是因为他把网页内容进行了下载,同时生成一个文件。这是默认调用GET的方法。
其实,CURL更多的是用来处理POST数据、上传文件等功能
例子如下:
PHP代码
- <?
-
-
-
-
-
-
- $url = 'http://www.ericgiguere.com/tools/http-header-viewer.html';
-
-
- function disguise_curl($url)
- {
- $curl = curl_init();
-
-
-
- $header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,";
- $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
- $header[] = "Cache-Control: max-age=0";
- $header[] = "Connection: keep-alive";
- $header[] = "Keep-Alive: 300";
- $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
- $header[] = "Accept-Language: en-us,en;q=0.5";
- $header[] = "Pragma: ";
-
- curl_setopt($curl, CURLOPT_URL, $url);
- curl_setopt($curl, CURLOPT_USERAGENT, 'Googlebot/2.1 (+http://www.google.com/bot.html)');
- curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
- curl_setopt($curl, CURLOPT_REFERER, 'http://www.google.com');
- curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
- curl_setopt($curl, CURLOPT_AUTOREFERER, true);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($curl, CURLOPT_TIMEOUT, 10);
-
- $html = curl_exec($curl);
- curl_close($curl);
-
- return $html;
- }
-
-
- $text = disguise_curl($url);
- echo $text;
- ?>
上面是一个比较完整的实现。特别需要注意的是header头部的发送,最初看手册的时候,我一以为CURLOPT_HTTPHEADER所需的数组是键值对应的,即:
PHP代码
- $header = array('Keep-Alive'=>'300');
现实的残酷告诉我,不应该这么用,而是象上面的例子那样,每条header为数组的一个记录。
切记切记啊
Tags: curl, curlopt, httpheader, libcurl, charset
PHP | 评论:0
| 阅读:33154
Submitted by gouki on 2008, November 16, 6:02 PM
經過指點,獲悉原文為:http://www.felixwoo.com/archives/247
我轉貼的文章來源:http://www.knowsky.com/442121.html
PS:虽然我是从上面拷来的,但我并不建议打开这个网页看,因为,上面全是广告。个人猜测,代码也是他拷来的,但没有亲自验证,我也没法打包票。不过东西有点用,所以我也就COPY过来了。
内容如下:
最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业。对于初学者来说别说理解闭包了,就连文字叙述都很难看懂。撰写此文的目的就是用最通俗的文字揭开Javascript闭包的真实面目。
一、什么是闭包?
“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。看下面这段代码:
JavaScript代码
- function a(){
- var i=0;
- function b(){
- alert(++i);
- }
- return b;
- }
- var c = a();
- c();
这段代码有两个特点:
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
我猜想你一定还是不理解闭包,因为你不知道闭包有什么作用,下面让我们继续探索。
二、闭包有什么作用?
简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。这是对闭包作用的非常直白的描述,不专业也不严谨,但大概意思就是这样,理解闭包需要循序渐进的过程。
在上面的例子中,由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。
那 么我们来想象另一种情况,如果a返回的不是函数b,情况就完全不同了。因为a执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会被b引 用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被GC回收。(关于Javascript的垃圾回收机制将在后面详细介绍)
三、闭包内的微观世界
如 果要更加深入的了解闭包以及函数a和嵌套函数b的关系,我们需要引入另外几个概念:函数的执行环境(excution context)、活动对象(call object)、作用域(scope)、作用域链(scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。
1、当定义函数a的时候,js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的“环境”,如果a是一个全局函数,则scope chain中只有window对象。
2、当函数a执行的时候,a会进入相应的执行环境(excution context)。
3、在创建执行环境的过程中,首先会为a添加一个scope属性,即a的作用域,其值就为第1步中的scope chain。即a.scope=a的作用域链。
4、 然后执行环境会创建一个活动对象(call object)。活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后,把活动对象添加到a 的作用域链的最顶端。此时a的作用域链包含了两个对象:a的活动对象和window对象。
5、下一步是在活动对象上添加一个arguments属性,它保存着调用函数a时所传递的参数。
6、最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。
到此,整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给c,又函数b的作用域链包含了对函数a的活动对象的引用,也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被GC回收。
当函数b执行的时候亦会像以上步骤一样。因此,执行时b的作用域链包含了3个对象:b的活动对象、a的活动对象和window对象,如下图所示:(这里看了一下,确实没有图,看来果然是拷贝过来的,稍稍验证了我的说法,呵呵。。。。唉。可惜我确实不知道原文在哪里,不过,我是从他的网站拷来的,还是给他一个链接,毕竟我的资料来源是该网站)
![大小: 56.19 K
尺寸: 500 x 180
浏览: 1981 次
点击打开新窗口浏览全图](https://neatstudio.com/attachments//date_200811/74f07efc62fe98091a0017cc9bb24980.jpg)
(附上原文圖片)
如图所示,当在函数b中访问一个变量的时候,搜索顺序是先搜索自身的活动对象,如果存在则返回,如果不存在将继续搜索函数a的活动对象,依 次查找,直到找到为止。如果整个作用域链上都无法找到,则返回undefined。如果函数b存在prototype原型对象,则在查找完自身的活动对象 后先查找自身的原型对象,再继续查找。这就是Javascript中的变量查找机制。
四、闭包的应用场景
1、保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。
2、在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。
以上两点是闭包最基本的应用场景,很多经典案例都源于此。
五、Javascript的垃圾回收机制
在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。
Tags: 闭包, closure, javascript, archive
Javascript | 评论:2
| 阅读:24214
Submitted by gouki on 2008, November 15, 10:01 AM
假设的应用场景
我假定博客园要在首页为群组开辟一块空间,推广小组,小组能在首页显示的条件有四个:
1. 页面点击量大于10w
2. 小组人数大于1000
3. 小组帖子数大于10000
4. 小组在2007年之前创建
现在假定4个条件都满足的小组只有两个,太少了,推广位可以推广10个小组;这时候运营人员要求这4个条件中满足3个但是第4个条件不满足的小组算符合条件的小组,如果4个条件都满足就认为这个小组太火了,不需要在首页推广它了。业务逻辑想清楚了,下一步就该写代码了,数据逻辑层的代码的任务假定交给我了,我要考虑满足4个条件中3个成立的sql怎么写。
为了叙事方便,我们假如小组表的名字为Group,相关的条件字段是Pv,UserCount,PostCount,CreateTime:分别表示小组的点击量,人数,帖子数,创建时间.
我来写sql语句,上面的四个条件满足至少3个,有多少种情况呢?这是一个组合问题,一共有多少种的公式我已经忘记了,我要根据感觉写写看:
SELECT * FROM Group
WHERE (Pv>100000 AND UserCount>1000 AND PostCount>10000 AND CreateTime > 20070101)
OR (Pv>100000 AND UserCount>1000 AND PostCount<10000 AND CreateTime < 20070101)
OR (Pv>100000 AND UserCount<1000 AND PostCount>10000 AND CreateTime < 20070101)
这个Sql语句条件还行,但是我们的题目是n个条件m个条件成立,如果多了还这么写,恐怕就很累了,能不能改进呢?答案是肯定的,要不我就不写这篇随笔了,呵呵
SELECT * FROM Group
WHERE
(CASE Pv WHEN Pv>100000 THEN 1 ELSE 0 END) --这是PV的条件成立则为1,否则为0
+(CASE UserCount WHEN UserCount > 1000 THEN 1 ELSE 0 END) --用户数条件
+(CASE PostCount WHEN PostCount > 10000 THEN 1 ELSE 0 END) --帖子数条件
+(CASE CreateTime WHEN CreateTime < 20070101 THEN 1 ELSE 0 END) --时间条件
= 3
如果上面的三个表达式加起来值是3就说明恰好满足三个条件,如果是两个条件就是等于2,如果扩展为n个条件m个条件成立也很容易写,很容易维护、修改。
这是一个sql条件语句的技巧,希望对你有用。
本文假设的场景纯属虚设,请勿遐想。J
原文地址:http://www.cnblogs.com/yukaizhao/archive/2008/11/14/sql_condition_m_n.html
PS:
顺便说明一下,在mysql中也支持这样的用法(4我没有试过,但是5是支持这样的用法的。)虽然这样的用法比较容易写和维护及修改,但看上去还是有点妖。而且,效率不一定能保证。
Tags: 数据库, 条件查询, where
DataBase | 评论:0
| 阅读:25680