10月 29
Test First Guidelines
Sean Shubin
01/25/2002
Sean Shubin has begun using Test-First development. He wanted to share these ideas and guidelines with us.

Contents:

This document is my attempt to filter out guidelines about Test First Design from the XP series of books. Thanks to Denise Phillips and Ron Jeffries for their input. It is not my intent to justify Test First Design, I just want summarize what martin Fowler's Refactoring and the XP texts have to say on the subject. If you see anything that you think contradicts these sources, please e-mail me with the book and page number. I am still working on samples for each of these guidelines. If you find any of them completely confusing, send me an e-mail to let me know which ones I need to work on. Send e-mail to Sean Shubin, (remove the "nospam" portion of the e-mail address).

The tests should drive you to write the code, the reason you write code is to get a test to succeed, and you should only write the minimal code to do so. Note that test-first-design is more than just unit testing. Unit testing by itself does not change the design of the code. In addition to documenting how code should be used, test-first-design helps you keep the design simple right from the start, and keeps the design easy to change.

As project complexity grows, you may notice that writing automated tests gets harder to do. This is your early warning system of overcomplicated design. Simplify the design until tests become easy to write again, and maintain this simplicity over the course of the project.
Guidelines for test first design:

* The name of the test should describe the requirement of the code
* There should be at least one test for each requirement of the code. Each possible path through of the code is a different requirement
* Only write the simplest possible code to get the test to pass, if you know this code to be incomplete, write another test that demonstrates what else the code needs to do
* A test should be similar to sample code, in that it should be clear to someone unfamiliar with the code as to how the code is intended to be used
* If a test seems too large, see if you can break it down into smaller tests
* If you seem to be writing a lot of code for one little test, see if there are other related tests you could write first, that would not require as much code
* Test the goal of the code, not the implementation
* One test/code/simplify cycle at a time. Do not write a bunch of tests, and try to get them working all at once
* Keep writing tests that could show if your code is broken, until you run out of things that could possibly break
* When choosing an implementation, be sure to choose the simplest implementation that could possibly work
* If you are unsure about a piece of code, add a test you think might break it
* A test is one specific case, for which there is a known answer
* If all of the tests succeed, but the program doesn't work, add a test
* Tests should be as small as possible, before testing a requirement that depends on multiple things working, write a test for each thing it depends
* Tests should not take longer than a day to get working, typical test/code/simplify cycles take around 10 minutes
* Don't test every single combination of inputs. Do test enough combinations of inputs to give you confidence that the any code that passes the test suite will work with every single combination of inputs
* Do not write a single line of code that doesn't help a failing test succeed. (Clarification for GUI's, some aspects of GUI's are impossible to test automatically, so it will have to be an acceptance test that drives you two write some GUI code. Use automated testing whenever possible)
* Do not fix a bug until you have written a test that demonstrates the bug

What is the simplest code? (Paraphrased from the "Extreme Programming" series of books)

* All of the tests run
* There is no duplicate code (any given code segment or structural pattern should appear "once and only once")
* Clarity. The code and tests communicate the intent as clearly as possible
* The code is minimal (no classes or methods unnecessary to get the tests to pass)

The Test-Code-Simplify cycle (Quoted verbatim from "Extreme Programming Applied", p159)

* Write a single test
* Compile it. It shouldn't compile, because you haven't written the implementation code it calls
* Implement just enough code to get the test to compile
* Run the test and see it fail
* Implement just enough code to get the test to pass
* Run the test and see it pass
* Refactor for clarity and "once and only once"
* Repeat

Online Examples of Test First Design:

Roman numeral converter example

http://www.differentpla.net/~roger/devel/xp/test_first/

Sample application that calculates bowling score

http://www.objectmentor.com/publications/xpepisode.htm

Books:

"Refactoring" and "Design Patterns" tell you how to maintain a simple design.

The "Extreme Programming" series explains test-first design in detail, and was the primary resource I used to put together this set of guidelines.

来源:http://xprogramming.com/xpmag/testFirstGuidelines.htm
最近感觉想翻译的东西太多了,有一些就纯粹转载了。有时间再翻译。
Defined tags for this entry: , , ,

作者 rollenc

Bookmark Test First Guidelines  at del.icio.us Digg Test First Guidelines Mixx Test First Guidelines Bloglines Test First Guidelines Technorati Test First Guidelines Fark this: Test First Guidelines Bookmark Test First Guidelines  at YahooMyWeb Bookmark Test First Guidelines  at Furl.net Bookmark Test First Guidelines  at reddit.com Bookmark Test First Guidelines  at blinklist.com Bookmark Test First Guidelines  at Spurl.net Bookmark Test First Guidelines  at NewsVine Bookmark Test First Guidelines  at Simpy.com Bookmark Test First Guidelines  at blogmarks Bookmark Test First Guidelines  with wists Bookmark Test First Guidelines  at Ma.gnolia.com wong it! Bookmark using any bookmark manager! Stumble It!
10月 27
From: http://www.devshed.com/c/a/PHP/Unit-Testing/
Unit Testing
单元测试

Having a formalized unit testing infrastructure for your projects will save you time in the long run, especially when looking for bugs in code. This article introduces you to setting up a unit testing framework. It is excerpted from chapter 6 of the book Advanced PHP Programming, written by George Schlossnagle (Sams; ISBN: 0672325616).
在正式的单元测试编程的基础上,你可以给你的程序开发节省下不少时间,特别是查找和修复BUG时的时间。本文介绍了如何建立一个测试框架。本文引于《告急PHP编程》第六章,作者:George Schlossnagle (Sams; ISBN: 0672325616).

Testing and engineering are inextricably tied forever.
测试和开发紧密联系

All code is tested at some point—perhaps during its implementation, during a dedicated testing phase, or when it goes live. Any developer who has launched broken code live knows that it is easier to test and debug code during development than after it goes into production.
所有的代码都在同一时候被测试,很可能是在程序执行的时候,或者是在专门的测试阶段,或者在程序发布后。程序员们都知道,在开发阶段中,在开发阶段修复程序BUG比发布后再修复要容易。

Developers give many excuses for not testing code until it is too late. These are some of the popular ones:
程序员给没有经过测试的代码找了很多的理由,常见的有:
* The project is too rushed. 程序开发过于匆忙。
* My code always works the first time. 程序在开始是可以正常运行的。
* The code works on my machine. 这些代码在我的机器上是可以正常运行的。

Let's explore these excuses. First, projects are rushed because productivity lags. Productivity is directly proportional to the amount of debugging required to make code stable and working. Unfortunately, testing early and testing late are not equal cost operations. The problem is two-fold:
我们来研究这几个理由。首先,工程匆忙是因为效率不佳,对代码的稳定性和正确性的调试直接影响到开发效率。不幸的是。在不同时候对代码进行调试所需要的花费是不一样的。从下面几点来说明:

* In a large code base that does not have a formalized testing infrastructure, it is hard to find the root cause of a bug. It's a needle-in-a-haystack problem. Finding a bug in a 10-line program is easy. Finding a bug in 10,000 lines of included code is a tremendous effort.
* 项目中没有基于一个正式的测试基础,这导致很难查找到BUG的来源。在10行代码中找出错误是简单的,但是在10,000行代码中,而且包含很多文件包含关系的代码中找出一个错误则是一场噩梦。

* As the code base grows, so do the number of dependencies between components. Seemingly innocuous changes to a "core" library—whether adding additional features or simply fixing a bug—may unintentionally break other portions of the application. This is known as refactoring. As the size and complexity of software grow, it becomes increasingly difficult to make these sorts of changes without incurring time costs and introducing new bugs.
*
* All software has bugs. Any developer who claims that his or her software is always bug-free is living in a fantasy world.
* System setups are all slightly different, often in ways that are hard to anticipate. Differing versions of PHP, differing versions of libraries, and different file system layouts are just a few of the factors that can cause code that runs perfectly on one machine to inexplicably fail on another.
Defined tags for this entry: , ,

作者 rollenc

Bookmark Unit Testing 单元测试  at del.icio.us Digg Unit Testing 单元测试 Mixx Unit Testing 单元测试 Bloglines Unit Testing 单元测试 Technorati Unit Testing 单元测试 Fark this: Unit Testing 单元测试 Bookmark Unit Testing 单元测试  at YahooMyWeb Bookmark Unit Testing 单元测试  at Furl.net Bookmark Unit Testing 单元测试  at reddit.com Bookmark Unit Testing 单元测试  at blinklist.com Bookmark Unit Testing 单元测试  at Spurl.net Bookmark Unit Testing 单元测试  at NewsVine Bookmark Unit Testing 单元测试  at Simpy.com Bookmark Unit Testing 单元测试  at blogmarks Bookmark Unit Testing 单元测试  with wists Bookmark Unit Testing 单元测试  at Ma.gnolia.com wong it! Bookmark using any bookmark manager! Stumble It!
10月 6
原地址:http://www.phpbuilder.com/columns/kassemi20050613.php3?aid=923


XMLHttpRequest and AJAX for PHP programmers, Part 2

PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分

James Kassemi

翻译:rollenc


Let's Jump Right In!

我们继续!


This week's article takes off where last week's tutorial left off--we're about to jump into the creation of the PHP backend! If you haven't read the previous article, we recommend that you begin there before moving forward so you don't miss anything.

通过上周的学习,本周文章开始正式开始了。我们准备开始编辑PHP后台!如果你还没有阅读上一篇文章,我们建议你先阅读它,不要拉下必要的知识。


Calling the Functions

调用函数


Now, how is the products.html page supposed to call these functions? We want to be able to let the user select an item, and then load the values based on that selection. Using a "Search" or "Go" button is a little archaic, so let's use the onChange method, which we can use to call javascript functions whenever the user changes the selected item. Change the <select> tag in products.html to look like this:

那现在,products.html如何来调用这些函数呢 ?我们需要在用户选择条目后,加载与这个条目相关的信息。使用“搜索”或“go”显得有点老套,所以我们使用了onChange方法(事件),当用户改变选择的条目时,我们通过JAVASCRIPT来调用。将products.html文件中的<select>标签修改成这样:





<select name="select_category_select" onChange="getProducts();" />



Whenever a user changes his selection in the select box, getProducts() will be called. So, now that we've got a script that sends some data to a PHP file and receives data returned from a PHP file, we need to program the PHP file.

一旦用户改变了选择框中的选项,getProducts()就会被调用。这样我们已经编写好了发送请求和接受数据的脚本,我们接下来需要的是编写PHP文件。



Programming the PHP back-end

编写PHP后台


In our javascript function getProducts(), we made a call to the following:

在Javascript函数getProducts(),我们做了这样的调用:



    http.open('get', 'internal_request.php?action=get_products&id=' + document.getElementById('product_categories').selectedIndex);
 



So we obviously need a PHP script that handles the action and id arguments from a GET request.



<?php
/* You should implement error checking, but for simplicity, we avoid it here */
/* 你可以进行错误处理,但为了简洁,我们略过了这些。 */
if($_GET['action'] == 'get_products'){
    /* We're here to get the product listing...
        You can obviously change this file to include many
        different actions based on the request.
    */

    switch($_GET['id']){
        /* We had the following in our list.
                0 Audio
                1 Games
                2 Internet
            The integer value on the left is the value
            corresponding to the javascript selectedIndex
            property.*/

        case 0: // Audio Programs
            /* Print HTML to fill the product_cage <div>
                Any output to the browser will be
                retrieved in the XMLHttpRequest object's
                responseText property */

            echo '
                <ul>
                    <li>CDex</li>
                    <li>CoolEdit</li>
                    <li>Winamp</li>
                    <li>XMMS</li>
                </ul>'
;
            break;
        case 1: //Games
            echo '
                <ul>
                    <li>Blackjack</li>
                    <li>Calculatron</li>
                    <li>Hold\'em</li>
                    <li>Minesweeper</li>
                    <li>Tetris</li>
                </ul>'
;
            break;
        case 2: //Internet
            echo '
                <ul>
                    <li>Epiphany</li>
                    <li>Internet Explorer</li>
                    <li>Mozilla</li>
                    <li>Netscape</li>
                    <li>Opera</li>
                    <li>Safari</li>
                </ul>'
;
            break;
        default:
            echo '<b>You didn\'t select an item from above!</b>';
            break;     
    }   
}
?>
 


Save the above in a file called internal_request.php.
保存以上文件为internal_request.php.

Browse to products.html using your favorite browser, and select one of the category options. You'll see the product_cage div change according to which items you selected. It may not seem like much with all the work that you put into it, but giving the user the ability to search and receive results while on the same page is great. Imagine posting to a forum without leaving the thread, or even something similar to the above for a large corporation with thousands of products. Bandwidth saved is money saved, and your company will no doubt appreciate that.
在你喜欢的浏览器中打开products.html,选择一个选项,你会发现,名称为product_cage的DIV内容根据你的选择改变了。这并不是所有的好处。想象一下,如果在论坛上恢复一篇文章而不需要重新刷新本页,或者当网站拥有成千上万的产品时,毫无疑问,贵公司会因为流量的节省而高兴的。
There are many resources available to learn more about AJAX and the XMLHttpRequest object, and now that you know the basics, you shouldn't have any problem expanding your knowledge to fit your application. Good luck!
有许多可以利用和学习的Ajax,XMLHttpRequest的知识,到现在你只是了解到了一些基础知识而已。希望你不会因为进一步学习和应用而遇到困惑。祝你好运!
Source for Included File: products.html
products.html的源代码:


<html>

    <head>

        <title>CompanyXYZ Software</title>

        <script language="javascript" type="text/javascript"

            src="./internal_request.js">



        </script>

    </head>

    <body>

        <div id="product_categories">

            <!--Category selection box...-->

            <form name="form_category_select">



                <select name="select_category_select" onChange="getProducts();">

                    <option>Audio</option>

                    <option>Games</option>



                    <option>Internet</option>

                </select>

            </form>

        </div>

        <div id="product_cage">



            <!--This is where we'll be displaying the products once they're loaded-->

            ^ Please select a category from above.

        </div>

    </body>

</html>



Source for Included File: internal_request.js
products.html的源代码:
/* The following function creates an XMLHttpRequest object... */


function createRequestObject(){

    var request_o; //declare the variable to hold the object.

    var browser = navigator.appName; //find the browser name

    if(browser == "Microsoft Internet Explorer"){

        /* Create the object using MSIE's method */

        request_o = new ActiveXObject("Microsoft.XMLHTTP");

    }else{

        /* Create the object using other browser's method */

        request_o = new XMLHttpRequest();

    }

    return request_o; //return the object

}



/* You can get more specific with version information by using

    parseInt(navigator.appVersion)

    Which will extract an integer value containing the version

    of the browser being used.

*/

/* The variable http will hold our new XMLHttpRequest object. */

var http = createRequestObject();



/* Function called to get the product categories list */

function getProducts(){

    /* Create the request. The first argument to the open function is the method (POST/GET),

        and the second argument is the url...

        document contains references to all items on the page

        We can reference document.form_category_select.select_category_select and we will         

        be referencing the dropdown list. The selectedIndex property will give us the

        index of the selected item.

    */

    http.open('get', 'internal_request.php?action=get_products&id='

            + document.form_category_select.select_category_select.selectedIndex);

    /* Define a function to call once a response has been received. This will be our

        handleProductCategories function that we define below. */

    http.onreadystatechange = handleProducts;

    /* Send the data. We use something other than null when we are sending using the POST

        method. */

    http.send(null);

}



/* Function called to handle the list that was returned from the internal_request.php file.. */

function handleProducts(){

    /* Make sure that the transaction has finished. The XMLHttpRequest object

        has a property called readyState with several states:

        0: Uninitialized

        1: Loading

        2: Loaded

        3: Interactive

        4: Finished */

    if(http.readyState == 4){ //Finished loading the response

        /* We have got the response from the server-side script,

            let's see just what it was. using the responseText property of

            the XMLHttpRequest object. */

        var response = http.responseText;

        /* And now we want to change the product_categories <div> content.

            we do this using an ability to get/change the content of a page element

            that we can find: innerHTML. */

        document.getElementById('product_cage').innerHTML = response;

    }

}



Source for Included File: internal_request.php
internal_request.php的源代码:

<?php
/* You should implement error checking, but for simplicity, we avoid it here */
if($_GET['action'] == 'get_products'){
    /* We're here to get the product listing...
        You can obviously change this file to include many
        different actions based on the request.
    */

    switch($_GET['id']){
        /* We had the following in our list.
                0 Audio
                1 Games
                2 Internet
            The integer value on the left is the value
            corresponding to the javascript selectedIndex
            property.*/

        case 0: // Audio Programs
            /* Print HTML to fill the product_cage
                Any output to the browser will be
                retrieved in the XMLHttpRequest object's
                responseText property */

            echo '
                <ul>
                    <li>CDex</li>
                    <li>CoolEdit</li>
                    <li>Winamp</li>
                    <li>XMMS</li>
                </ul>'
;
            break;
        case 1: //Games
            echo '
                <ul>
                    <li>Blackjack</li>
                    <li>Calculatron</li>
                    <li>Hold\'em</li>
                    <li>Minesweeper</li>
                    <li>Tetris</li>
                </ul>'
;
            break;
        case 2: //Internet
            echo '
                <ul>
                    <li>Epiphany</li>
                    <li>Internet Explorer</li>
                    <li>Mozilla</li>
                    <li>Netscape</li>
                    <li>Opera</li>
                    <li>Safari</li>
                </ul>'
;
            break;
        default:
            echo '<b>You didn\'t select an item from above!</b>';
            break;     
    }   
}
?>
 
Defined tags for this entry: , , , , , ,

作者 rollenc

Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at del.icio.us Digg PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分 Mixx PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分 Bloglines PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分 Technorati PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分 Fark this: PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分 Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at YahooMyWeb Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at Furl.net Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at reddit.com Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at blinklist.com Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at Spurl.net Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at NewsVine Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at Simpy.com Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at blogmarks Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  with wists Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX 第二部分  at Ma.gnolia.com wong it! Bookmark using any bookmark manager! Stumble It!
10月 5
Link:http://www.phpbuilder.com/columns/kassemi20050606.php3?aid=917

XMLHttpRequest and AJAX for PHP programmers
php程序中的XMLHttpRequest 和 AJAX

Introduction:
前言:

Although the concept isn't entirely new, XMLHttpRequest technology is implemented on more sites now than ever. Compatibility is no longer an issue (IE, Mozilla and Opera all support it), and the benefits to using it are amazing. There are too many PHP programmers avoiding any work with javascript beyond simple form validation, and for good reason. It's difficult to keep several languages proficiently under your belt. But using the XMLHttpRequest object is not as hard as everybody thinks, and you don't need to buy and memorize another reference manual.
虽然 XMLHttpRequest概念并不是新的,但最近在网站上的应用远多于以前。兼容性也不存在问题了(IE, Mozilla and Opera都支持),其应用有时也是令人惊奇的。很多PHPer通过这一方式来避免使用javascript来验证简单的表单输入。同时使用几种语言是很困难的。而使用XMLHttpRequest并不象人们想象的那么难,你也不需要去为此买一本参看书或者记忆一本参考手册。

Let's Get To It!
开始!

Asynchronous JavaScript and XML, or AJAX is a method of sending and receiving data (usually XML) from a server-side application through javascript. Since javascript offers the ability to change the contents of a web page on-the-fly, this technique allows web programmers to venture closer to programming truly interactive web applications similar to those built with Java and ActiveX.
Ajax(Asynchronous JavaScript and XML)是通过javascript去请求和获取一个服务器端操作。由于这种功能,javascript可以改变网页中的内容。这种技术使得web程序员可以像Java和ActiveX程序一样进行交互设计。

As PHP developers, it might seem tempting to avoid the use of Javascript and leave it to the designer. After all, we aren't usually programming the UI, but the processing components required by the UI. The distinction between the two is disappearing. Here's a simple diagram that demonstrates just how AJAX works:
PHP开发人员更倾向于不使用javascript,而把他交给前台设计人员来处理。毕竟,我们不常对UI进行编码。但AJAX过程中的一些部分是在UI中的。这两者没有什么区别。这里是演示AJAX如何运行的一个简单图表。

点击查看原始尺寸

If you're working for a small or medium sized company interested in implementing AJAX solutions, you might end up responsible for figuring out how.
如果你任职于一家中小型公司,仅仅对AJAX的解决方案感兴趣的话,你可能仅仅能够理解到AJAX是如何工作的而已。

XMLHttpRequest objects can be a simple way of getting data to and from a PHP application while keeping your client right at home on the same page. Our example today will allow a user to select a specific piece of software that your company makes. We will show a selection box with several categories. When a user selects a category, a request is sent to a PHP application which returns a list of applicable software. The information is used to generate a list of the results underneath the selection box. Since the information is not loaded with the initial page, your company saves bandwidth, and because the user doesn't have to bounce from page to page for results, he will find your company's page more inviting and faster to load.
XMLHttpRequest对象在客户端的同一页面可以简单的从获得数据后从PHP程序结果。这里的例子允许用户选择贵公司的程序模块。我们通过一个选择框来实现。当用户选择一个种类时,就会发送一个请求到PHP程序,以得到应用程序的列表。这些生成的列表信息属于用户所选择类别之下。由于信息不需要在首次全部载入,这为贵公司省下了流量。对用户来讲,他们不需要在页面间跳来跳去,他们对觉得贵网站很有吸引力,加载也很快。

Javascript for PHP Programmers
PHPer需要的Javascript

Since we'll be working with Javascript, it's good to get a basic tutorial given a background in PHP.
因为我们需要编写Javascript,先通过PHP背景来了解一下Javascript语言的基础。

Variables:
变量:

Variables in javascript are declared in much the same was as in PHP. To declare a variable in javascript, use the following:
Javascript中的变量声明与PHP中的很相似。在Javascript中声明一个变量如下:


var varname = varvalue; //Declaring your variable is not mandatory, but good practice.
var varname = varvalue; //变量声明不是必须的,但这是一个好的习惯
 


Control Structures:
控制结构:
PHP and javascript have a very similar way of using these as well... You can use if/else statements, switch statements, for and while loops and nested loops all with PHP syntax. If/elseif/else statements are a little different, but not much:
PHP和Javascript具有非常相似的语法结构,你可以使用PHP语法中的if/else句型,swicth句型,for和while循环和嵌套循环。if/elseif/else句型有一点点区别。


var variable1 = 1; //Declare a variable.
if(variable1 == 1){
    // Increment variable value by 1
    variable1++;
    /* The following brings up a message box, a handy way of checking variable values as you
                    go. Be careful not to use these in loops that are too long. */

    alert(variable1);
}else if(variable1 == 2){ //Elseif's in javascript require a space between the else and if.javascript中Elseif一定需要一个空格
    for(i=0;i < 20;i++){ //For loop.
        variable1++;
    }
        switch(variable1){ //Switch conditional
               case 22:
                   alert("variable 1 has value of 22!");
                   break;
               default:
                   alert("didn't have value of 22!");
            break;
    }
}else{
    alert('The final else statement');
}
 


Functions
函数
To declare a function in javascript, use the following:
在javascript中声明一个函数的方式如下:


function functioname(argument1, argument2, argument3){
    /* Arguments not provided will be null */
    if(argument3 == null){
        return argument1 + argument2
    }else{
        return argument1 + argument2 + argument3
    }
}

/* And call it with */
alert(functionname(1, 2)); //returns 3
/* or */
alert(functionname(1, 2, 3)); //returns 6
 


Other than the difference with default values for optional arguments, you should assign a default when a passed argument has a null value.
和PHP不同的是可选参数,你需要比较它是否是空的,再赋给它一个默认值。

Using Javascript in a Document:
在文档中使用Javascript

Javascript can be included in your document in two ways, similar to CSS inclusion:
Javascript可以通过两种方式在文档中使用,与CSS很像:



<!--Placing your javascript in the head tag of your html document is the standard-->

<!-- 把你的代码放在head标签间 -->

<script language="javascript" type="text/javascript" src="./javascript_file.js"></script>

<script language="javascript" type="text/javascript">



    /*Javscript code goes in here*/

    alert("Hello World!");

</script>



The first way is to link to the file directly, and the second is to include it on the page itself. If your code is getting long and is used on multiple pages, it is preferable to use the first method, as the browser will cache the file for future use. And that's all you need to know about Javascript to continue.
第一种方式是从文件中引用,第二种是在文档自身调用。如果你的代码需要很长后者需要在多个页面中使用的话,最好使用地一种方法,浏览器会缓存这些文件以便将来之用。现在你需要的是继续看下文。

Developing the Initial Page
第一个页面
Below we're going to be creating the page the user loads to view your companies products.
以下我们准备建立一个用户调用和查看公司产品的页面。



<html>

    <head>

        <title>CompanyXYZ Software</title>

        <script language="javascript" type="text/javascript"

            src="./internal_request.js">



        </script>

    </head>

    <body>

        <div id="product_categories">

            <!--Category selection box...-->

            <form name="form_category_select">



                <select>

                    <option>Audio</option>

                    <option>Games</option>

                    <option>Internet</option>



                </select>

            </form>

        </div>

        <div id="product_cage">

            <!--This is where we'll be displaying the products once they're loaded-->

            ^ Please select a category from above.

        </div>



    </body>

</html>



The above HTML first links to a javascript file, internal_request.js, and displays a page with two <div> tags, the second of which is where we'll be displaying our data. Go ahead and copy the above code into a file called products.html.
以上的HTML文件第一行指向了一个Javascript文件,internal_request.js,页面通过两个DIV标签来显示,我们会在第二个标签里显示我们的内容。复制以上代码到一个文件中,保存为products.html

Creating the XMLHttpRequest Object
建立XMLHttpRequest对象

The XMLHttpRequest object works differently in Internet Explorer and Mozilla-like browsers. To create an XMLHttpRequest object in IE, the following can be used:
XMLHttpRequest对象调用方式在Internet Explorer和Mozilla的浏览器不同,在IE中可以像如下方式使用:

var request_o = new ActiveXObject("Microsoft.XMLHTTP");
[/geshi

And the following works for supporting browsers other than IE:
这种方式对其他IE外的浏览器使用:
[geshi lang=javascript]
var request_o = new XMLHttpRequest();
 


Determining what browser you are working with and creating the appropriate object is simple:
兼容代码如下:

/* The following function creates an XMLHttpRequest object... */

function createRequestObject(){
    var request_o; //declare the variable to hold the object.
    var browser = navigator.appName; //find the browser name
    if(browser == "Microsoft Internet Explorer"){
        /* Create the object using MSIE's method */
        request_o = new ActiveXObject("Microsoft.XMLHTTP");
    }else{
        /* Create the object using other browser's method */
        request_o = new XMLHttpRequest();
    }
    return request_o; //return the object
}

/* You can get more specific with version information by using
    parseInt(navigator.appVersion)
    Which will extract an integer value containing the version
    of the browser being used.
*/

 


Copy the above code into a file called internal_request.js, located in the same directory as the products.html file.
复制以上代码,保存到文件internal_request.js,与products.html放在同意目录。

We now have a function that will create an XMLHttpRequest object in internal_request.js, and we have an HTML file that calls upon the code in internal_request.js. Remember how we left the product selection <div> in products.html blank? Let's write the code that utilizes our createRequestObject function to get the list of products.
我们现在已经有了一个可以创建XMLHttpRequest对象的internal_request.js和调用这个JS的HTML文件,注意我们把DIV中的列表留空了。我们来写一段代码利用createRequestObject函数来的得到公司产品列表。


/* The variable http will hold our new XMLHttpRequest object. */
var http = createRequestObject();

/* Function called to get the product categories list */
function getProducts(){
    /* Create the request. The first argument to the open function is the method (POST/GET),
        and the second argument is the url...
        document contains references to all items on the page
        We can reference document.form_category_select.select_category_select and we will
        be referencing the dropdown list. The selectedIndex property will give us the
        index of the selected item.
    */

    http.open('get', 'internal_request.php?action=get_products&id='
            + document.form_category_select.select_category_select.selectedIndex);
    /* Define a function to call once a response has been received. This will be our
        handleProductCategories function that we define below. */

    http.onreadystatechange = handleProducts;
    /* Send the data. We use something other than null when we are sending using the POST
        method. */

    http.send(null);
}

/* Function called to handle the list that was returned from the internal_request.php file.. */
function handleProducts(){
    /* Make sure that the transaction has finished. The XMLHttpRequest object
        has a property called readyState with several states:
        0: Uninitialized
        1: Loading
        2: Loaded
        3: Interactive
        4: Finished */

    if(http.readyState == 4){ //Finished loading the response
        /* We have got the response from the server-side script,
            let's see just what it was. using the responseText property of
            the XMLHttpRequest object. */

        var response = http.responseText;
        /* And now we want to change the product_categories <div> content.
            we do this using an ability to get/change the content of a page element
            that we can find: innerHTML. */

        document.getElementById('product_cage').innerHTML = response;
    }
}
 


The above code should be appended to what you already have in the internal_request.js file.
以上的代码依赖于internal_request.js文件。

Conclusion
结论

We'll followup with the rest of this informative article next week, so be sure to visit us again for the conclusion! btw, don't miss the important Quick Tips listed below!
剩下的内容我们将在下周进行介绍,记得对本站的继续关注!顺便提一下,不要忘记以下的快速提示。

Quick Tip 1: (Using the POST method instead of GET):
The following will send the request to the PHP file using the POST method:
快速提示1:使用Post方法替代GET
下面是使用POST方法发送请求的例子:

    http.abort;
    http.open('post''back_end.php');
    http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    http.send('arg1=val1&arg2=val2&arg3=val3');
 


Quick Tip 2: (Parsing XML results):
快速提示2:(解析XML结果):

If you're receiving XML instead plain-text results from your processing PHP script, you can use the javascript DOM to parse them. Suppose you receive the following:
如果你从PHP程序返回XML结果而非纯文本结果,你可以使用Javascript DOM来解析他们。假设你得到了以下结果:

    <product_list>
        <product id="1">
            <name>EeasySMS</name>
            <version>2.2</version>
        </product>
        <product id="2">
            <name>BabyMon</name>
            <version>1.2</version>
        </product>
    </product_list>
 


To receive a DOM compatible response from our XMLHttpRequest object, instead of using the responseText property, substitute the responseXML property. In this case we'll refer to it by assigning it the variable XMLResponse.
为了使DOM模型可用,需要使用responseXML来替代responseText属性。这是,我们把结果赋给变量XMLResponse。

The product_list element contains two elements of interest: product elements. In order to get to these, we can use the following:
product_list元素包含有两个product元素,为了获得他们,可以使用以下代码:

/* Reference the product_list element to the variable product_list */
product_list = XMLReponse.getElementByTagName('product_id');

/* By substituting product_list for XMLResponse, we will be searching
    only the product_list element, not the entire response
    We also use getElementsByTagName, not getElementByTagName,
    since we are interested in all of the results, not just one. */


product_id = XMLResponse.getElementsByTagName('product');

/* getElementsByTagName produces an array, which we can access  like this:
    product_id[n], the same way we access an array item in PHP.
    Let's get the id attribute from the product elements like this: */


for(i=0; i < product_id.length; i++){ //length is the same as count($array)
    id = product_id[i].getAttribute('id') //Grabs the id attribute.
    /* To get the text from within a text node, we use firstChild.data
        for the corresponding element. */

    name = product_id[i].getElementByTagName('name').firstChild.data;
    version = product_id[i].getElementByTagName('version').firstChild.data;
}
 


This may seem like a bit to work with at first, but with a little work, you can get what you want to work. If you want to avoid this, you could use the responseText method, parsing the XML in PHP before sending it to the XMLHttpRequest object.
你可以少量的工作来使的这段代码来实现你自己的功能。如果你不想使用他,你可以在返回XMLHttpRequest对象前使用PHP来解析XML文档而使用responseText属性。

Quick Tip 3: (Relevant Links):
快速参考3:(相关参考)
* Microsoft XMLHttpRequest Documentation
* XMLHttpRequest @ Apple Developer Connection
* The DOM Model in Mozilla

About the Author:
关于作者:
James Kassemi lives in Albuquerque, New Mexico. He works mainly with PHP, programming for a variety of clients in the southwest.

翻译:rollenc
Defined tags for this entry: , , , , , ,

作者 rollenc

Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at del.icio.us Digg PHP程序员需要了解的XMLHttpRequest和AJAX Mixx PHP程序员需要了解的XMLHttpRequest和AJAX Bloglines PHP程序员需要了解的XMLHttpRequest和AJAX Technorati PHP程序员需要了解的XMLHttpRequest和AJAX Fark this: PHP程序员需要了解的XMLHttpRequest和AJAX Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at YahooMyWeb Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at Furl.net Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at reddit.com Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at blinklist.com Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at Spurl.net Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at NewsVine Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at Simpy.com Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at blogmarks Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  with wists Bookmark PHP程序员需要了解的XMLHttpRequest和AJAX  at Ma.gnolia.com wong it! Bookmark using any bookmark manager! Stumble It!
9月 9
sadfasdf
asdfasdf


英文中文




Optimizing PHP Scripts
By Leon Atkinson

June 20, 2001

One reason I like PHP is that it allows the freedom to quickly create Web applications without worrying about following all the rules of proper design. When it comes to rapid prototyping, PHP shines. With this power comes the responsibility to write clean code when it's time to write longer-lasting code. Sticking to a style guide helps you write understandable programs, but eventually you will write code that doesn't execute fast enough.

Optimization is the process of fine-tuning a program to increase speed or reduce memory usage. Memory usage is not as important as it once was, because memory is relatively inexpensive. However, shorter execution times are always desirable.

There are many tips for writing efficient programs, and I can hardly discuss them all here. And anyway, that would be like giving you a fish instead of teaching you to catch your own. This month, I will review the techniques I use for speeding up my PHP scripts.

When to optimize

Before you write a program, commit yourself to writing clearly at the expense of performance. Follow coding conventions, such as using mysql_fetch_row instead of mysql_result. But keep in mind that programming time is expensive, especially when programmers must struggle to understand code. The simplest solution is usually best.

When you finish a program, consider whether its performance is adequate. If your project benefits from a formal requirements specification, refer to any performance constraints. It's not unusual to include maximum page load times for Web applications. Many factors affect the time between clicking a link and viewing a complete page. Be sure to eliminate factors you cannot control, such as the speed of the network.

If you determine that your program needs optimization, consider upgrading the hardware first. This may be the least expensive alternative. In 1965, Gordon Moore observed that computing power doubled every 18 months. It's called Moore's Law. Despite the steep increase in power, the cost of computing power drops with time. For example, despite CPU clock speeds doubling, their cost remains relatively stable. Upgrading your server is likely less expensive than hiring programmers to optimize the code.

After upgrading hardware, consider upgrading the software supporting your program. Start with the operating system. Linux and BSD Unix have the reputation of squeezing more performance out of older hardware, and they may outperform commercial operating systems, especially if you factor in server crashes.

If your program uses a database, consider the differences between relational databases. If you can do without stored procedures and sub-queries, MySQL may offer a significant performance enhancement over other database servers. Check out the benchmarks provided on their Web site. Also, consider giving your database server more memory.

Two Zend products can help speed execution times of PHP programs. The first is the Zend Optimizer. This optimizes PHP code as it passes through the Zend Engine. It can run PHP programs 40% to 100% faster than without it. Like PHP, the Zend Optimizer is free. The next product to consider is the Zend Cache. It provides even more performance over the optimizer by keeping compiled code in memory. Some users have experienced 300% improvements. Contact Zend to purchase the Zend Cache.
Measuring performance

Before you can begin optimizing, you must be able to measure performance. The two tools I'll discuss are inserting HTML comments and using Apache's ApacheBench utility. PHP applications run on a Web server, but the overhead added by serving HTML documents over a network should be factored out of your measurements.

You need to isolate the server from other activity, perhaps by barring other users or even disconnecting it from the network. Running tests on a server that's providing a public site may give varying results, as traffic changes during the day. Run your tests on a dedicated server even if the hardware doesn't match the production server. Optimizations made on slower hardware should translate into relative gains when put into production.

The easiest method you can use is insertion of HTML comments into your script's output. This method adds to the overall weight of the page, but it doesn't disturb the display. I usually print the output of the microtime function. I insert a line like:

print("\n");

I place these calls to microtime at the beginning, end and at key points inside my script. To measure performance, I request the page in a Web browser and view the source. This produces lines like this:







The microtime function returns the number of seconds on the clock. The first figure is a fraction of seconds, and the other is the number of seconds since January 1, 1970. You can add the two numbers and put them in an array, but I prefer to minimize the affect on performance by doing the calculation outside of the script. In the example above, the first part of the script takes approximately 0.005 seconds, and the second part takes 0.03.

If you decide to calculate time differences, consider the method used in the example below. Entries to the clock array contain a one-word description followed by the output of microtime. The explode function breaks up the three values so the script can display a table of timing values. The first column of the table holds the number of seconds elapsed since the last entry.
//start clock
$clock[] = 'Start ' . microtime();

//fake some long process
sleep(2);
$clock[] = 'Connected ' . microtime();


//end clock
$clock[] = 'End ' . microtime();

//print clock
$entry = explode(' ', $clock[0]);
$lastVal = $entry[1] + $entry[2];
print('');
foreach($clock as $c)
{
$entry = explode(' ', $c);

print('');

print('');
print('');
print('');

print('');

$lastVal = $entry[1] + $entry[2];
}
print('
' . ($entry[1] + $entry[2] - $lastVal) .
'
' . $entry[0] . '' . ($entry[1] + $entry[2]) . '
');
?>

Inserting HTML comments is my favorite method, because it takes no preparation. But its big weakness is a small sample size. I always try three or four page loads to eliminate any variances due to caching or periodic server tasks.

The Apache Web server includes a program that addresses this problem by measuring the number of requests your server can handle. It's called ApacheBench, but the executable is "ab". ApacheBench makes a number of requests to a given URL and reports on how long it took. Here's an example of running 1000 requests for a plain HTML document:

~> /usr/local/apache/bin/ab -n 1000 http://localhost/test.html

This is ApacheBench, Version 1.3c <$Revision: 1.1.2.6 $> apache-1.3

Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Copyright (c) 1998-2000 The Apache Group, http://www.apache.org/

Server Software: Apache/1.3.19

Server Hostname: localhost

Server Port: 80

Document Path: /test.html

Document Length: 6 bytes

Concurrency Level: 1

Time taken for tests: 5.817 seconds

Complete requests: 1000

Failed requests: 0

Total transferred: 262000 bytes

HTML transferred: 6000 bytes

Requests per second: 171.91

Transfer rate: 45.04 kb/s received

Connnection Times (ms)

min avg max

Connect: 1 1 11

Processing: 3 3 16

Total: 4 4 27

I requested an HTML document to get an idea of the baseline performance of my server. Any PHP script ought to be slower than an HTML document. Comparing the figures gives me an idea of the room for improvement. If I found my server could serve a PHP script at 10 requests per second, I'd have a lot of room for improvement.

Keep in mind that I'm running ApacheBench on the server. This eliminates the effects of moving data over the network, but ApacheBench uses some CPU time. I could test from another machine to let the Web server use all the system resources.

By default, ApacheBench makes one connection at a time. If you use 100 for the -n option, it connects to the server one hundred times sequentially. In reality, Web servers handle many requests at once. Use the -c option to set the concurrency level. For example, -n 1000 -c 10 makes one thousand connections with 10 requests active at all times. This usually reduces the number of requests the server can handle, but at low levels the server is waiting for hardware, such as the hard disk.

The ApacheBench program is a good way to measure overall change without inconsistencies, but it can't tell you which parts of a script are slower than others. It also includes the overhead involved with connecting to the server and negotiating for the document using HTTP. You can get around this limitation by altering your script. If you comment out parts and compare performance, you can gain an understanding of which parts are slowest. Alternatively, you may use ApacheBench together with microtime comments.

Whichever method you use, be sure to test with a range of values. If your program uses input from the user, try both the easy cases and the difficult ones, but concentrate on the common cases. For example, when testing a program that analyzes text from a textarea tag, don't limit yourself to typing a few words into the form. Enter realistic data, including large values, but don't bother with values so large they fall out of normal usage. People rarely type a megabyte of text into a textarea, so if performance drops off sharply, it's probably not worth worrying about.

Remember to measure again after each change to your program, and stop when you achieve your goal. If a change reduces performance, return to an earlier version. Let your measurements justify your changes.
Attacking the slowest parts

Although there are other motivations, such as personal satisfaction, most people optimize a program to save money. Don't lose sight of this as you spend time increasing the performance of your programs. There's no sense in spending more time optimizing than the optimization itself saves. Optimizing an application used by many people is usually worth the time, especially if you benefit from licensing fees. It's hard to judge the value of an open-source application you optimize, but I find work on open-source projects satisfying as recreation.

To make the most of your time, try to optimize the slowest parts of your program where you stand to gain the most. Generally, you should try to improve algorithms by finding faster alternatives. Computer scientists use a special notation to describe the relative efficiency of an algorithm called big-O notation. An algorithm that must examine each input datum once is O(n). An algorithm that must examine each element twice is still called O(n) as linear factors are not interesting. A really slow algorithm might be O(n^2), or O of n-squared. A really fast algorithm might be O(n log n), or n times the logarithm of n. This subject is far too complex to cover here -- you will find lots of information on the Internet and in university courses. Understanding it may help you choose faster algorithms.

Permanent storage, such as a hard disk, is much slower to use than volatile storage, such as RAM. Operating systems compensate somewhat by caching disk blocks to system memory, but you can't keep your entire system in RAM. Parts of your program that use permanent storage are good candidates for optimization.

If you are using data stored in files, consider using a relational database instead. Database servers can do a better job of caching data than the operating system because they view the data with a finer granularity. Database servers may also cache open files, saving you the overhead in opening and closing files.

Alternatively, you can try caching data within your own program, but consider the lifecycle of a PHP script. At the end of the request, PHP frees all memory. If during your program you need to refer to the same file many times, you may increase performance by reading the file into a variable.

Consider optimizing your database queries, too. MySQL includes the EXPLAIN statement, which returns information about how the join engine uses indexes. MySQL's online manual includes information about the process of optimizing queries.

Here are two tips for loops. If the number of iterations in a loop is low, you might get some performance gain from replacing the loop with a number of statements. For example, consider a for loop that sets 10 values in an array. You can replace the loop with 10 statements, which is a duplication of code, but may execute slightly faster.

Also, don't recompute values inside a loop. Before the foreach statement appeared in PHP, I often wrote for($i=0; $i

Function calls ca