Giáo trình Apache PHP và MySQL
Dự án Apache là một sự cố gắng phát triển phần mềm cộng tác nhắm đến việc tạo ra một HTTP
server mạnh mẽ, có hạng thương mại, được đề cao,và mã nguồn thực hiện miễn phí. Dự án được
tham gia quản lý bởi một nhóm người tình nguyện trên toàn thế giới sử dụng internet và Web để
truyền thông , dựng kế hoạch và phát triển server . Những người tình nguyện này được biết đến
như là nhóm Apache. Thêm nữa, hàng trăm người sử dụng đã đóng góp các ý tưởng, mã và các
tàiliệu cho dự án.
Vào khoảng tháng 2 năm 1995, phần lớn phần mềm server được ưa chuộng trên web là tên miền
HTTP daemon công cộng được phát triển bởi Rob McCool tại trung tâm quốc gia của các ứng
dụng siêu máy tính, trường đạihọcIllinois, Urbana-Champaign.
Tuy nhiên, sự phát triển httpd đó đã bị ngưng trệ sau khi Rob rời NCSA vào khoảng giữa năm
1994, và rất nhiều nhà phát triển web đã phát triển phần mở rộng của chính họ và khắc phục lỗi
trong sự cần thiết của một sự phân phát chung. Một nhóm nhỏ của các nhà phát triển web này , đã
kết hợp với nhau thông qua e-mail là chính, kết hợp cùng với nhau cho mục đích phối hợp những
thay đổicủahọ ( trong hình thứccácmiếng vá).
Bằng cách dùng httpd 1.3 làm nền, họ đã thêm vào toàn bộ các miếng vá đã được công bố và các
tính năng cao cấp khác, thử nghiệm trên chính các server của họ, và cho ra đời phiên bản công
khaichính thứcđầu tiên (0.6.2) củaserver Apachetrong tháng 4 năm1995.
Server Apache ban đầu đã là một sự thành công lớn, nhưng họ cho rằng mã ban đầu cần phải
được kiểm tra kỹ lưỡng và thiết kế lại. Trong suốt tháng 5 năm và tháng 6 năm 1995, Robert
Thau đã thiết kế một kiến trúc server mới( mã được đặt tên là Shambhala) nó bao gồm một cấu
trúc module và API cho việc mở rộng được tốt hơn. Nhóm làm việc đã chuyển sang nền server
mới này từ tháng sáu và đã thêm các đặc điểm từ phiên bản 0.7.x, đưa đến kết quả trong Apache
0.8.8 ( vàcácanh emcủanó) trong tháng tám
urt ("raspberry"); // works as expected Đầu ra cho ví dụ này là: Making a bowl of acidophilus raspberry. 2.3_Các danh sách đối số chiều dài biến PHP4 cung cấp các danh sách đối số chiều dài biến trong các hàm được định nghĩa bởi người sử dụng . Điều này thực sự khá dễ dàng, dùng các hàm func_num_args(), func_get_arg() và hàm func_get_args(). Không yêu cầu cú pháp đặc biệt nào, và các danh sách đối số sẽ vẫn còn được cung cấp một cách rõ ràng với các định nghĩa hàm và sẽ trở nên thông thường. 3_Các giá trị trả về Các giá trị được trả về bằng cách dùng câu lệnh trả về tuỳ chọn. Bất kỳ kiểu nào cũng có thể được trả về, bao gồm cả các danh sách và các đối tượng. function square ($num) { return $num * $num; } echo square (4); // outputs '16'. Ta không thể trả về nhiều giá trị từ một hàm, nhưng các kết quả thông thường có thể đạt được bằng cách trả lại một danh sách. function small_numbers() { return array (0, 1, 2); } list ($zero, $one, $two) = small_numbers(); 49 Để trả về một tham chiếu từ một hàm, ta phải dùng toán tử tham chiếu & trong cả khai báo hàm và khi gán giá trị trả về cho một biến: function &returns_reference() { return $someref; } $newref =&returns_reference(); 4_ Old_function Câu lệnh old_function cho phép ta khai báo một hàm sử dụng một cú pháp giống hệt PHP/FI2 ( không thể ta phải thay thế ‘function’ bằng ‘old_function’). Đây là một đặc điểm không được tán thành, và chỉ được sử dụng bởi bộ chuyển đổi PHP/FI2 sang PHP3. Cảnh báo Các hàm được khai báo như old_function và không thể được gọi từ mã cục bộ của PHP. Chính vì vậy mà ta không thể dùng chúng trong các hàm như usort(), array_walk(), register_shutdown_function(). 5_Các hàm biến thiên PHP hỗ trợ khái niệm của các hàm biến thiên. Điều này có nghĩa là nếu một tên biến có các dấu ngoặc đơn được thêm vào nó, PHP sẽ tìm kiếm một hàm có cùng tên như thể cho dù biến định giá tới, và sẽ cố gắng để thực hiện chúng. Nói một cách khác, điều này có thể được dùng để thực hiện gọi trở lại, các bảng chức năng,và ra khỏi. Ví dụ về hàm biến thiên: <?php function foo() { echo "In foo()\n"; } function bar( $arg = '' ) { echo "In bar(); argument was '$arg'.\n"; } $func = 'foo'; $func(); $func = 'bar'; $func( 'test' ); ?> 50 IX_ CÁC LỚP VÀ CÁC ĐỐI TƯỢNG 1_Lớp Một lớp là một tập hợp của các biến và các hàm làm việc trong các biến này. Một lớp được định nghĩa sử dụng cú pháp sau: <?php class Cart { var $items; // Items in our shopping cart // Add $num articles of $artnr to the cart function add_item ($artnr, $num) { $this->items[$artnr] += $num; } // Take $num articles of $artnr out of the cart function remove_item ($artnr, $num) { if ($this->items[$artnr] > $num) { $this->items[$artnr] -= $num; return true; } else { return false; } } } ?> Điều này định nghĩa một lớp có tên là Cart gồm có một mảng kết hợp các thực phẩm trong cái xe chở và hai hàm để thêm và loại bỏ các phần tử từ cái xe chở này. Chú ý: Trong PHP4, chỉ có các khởi tạo hằng cho các biến var là được phép. Dùng các hàm khởi tạo cho các khởi tạo không là hằng số. /* None of these will work in PHP 4. */ class Cart { var $todays_date = date("Y-m-d"); var $name = $firstname; var $owner = 'Fred ' . 'Jones'; } /* This is how it should be done. */ class Cart { var $todays_date; var $name; var $owner; function Cart() { $this->todays_date = date("Y-m-d"); $this->name = $GLOBALS['firstname']; /* etc. . . */ } } Các lớp là các kiểu , do vậy, chúng là bản kế hoạch cho các biến thật sự. Ta phải tạo một biến có kiểu mong muốn với toán tử new. 51 $cart = new Cart; $cart->add_item("10", 1); Điều này tạo một đối tượng $cart của lớp Cart. Hàm add_item() của đối tượng đó đang được gọi để thêm một phần tử của thực phẩm số 10 vào xe chở. Các lớp có thể được mở rộng tới các lớp khác. Lớp được thừa hưởng hoặc được mở rộng có tất cả các biến và các hàm của lớp cơ sở và những gì bạn thêm vào định nghĩa được mở rộng. Điều này được thực hiện bằng cách dùng từ khoá extend. Đa thừa kế không được hỗ trợ. class Named_Cart extends Cart { var $owner; function set_owner ($name) { $this->owner = $name; } } Điều này định nghĩa một lớp Named_Cart mà có tất cả các biến và các hàm của Cart cộng với một biến thêm $owner và một hàm thêm set_owner(). Ta tạo một xe chở được chỉ định theo cách thông thường và bây giờ có thể thiết lập và lấy chủ của xe chở. Ta cũng có thể sử dụng các hàm xe chở thông thường trên các xe chở được chỉ định: $ncart = new Named_Cart; // Create a named cart $ncart->set_owner ("kris"); // Name that cart print $ncart->owner; // print the cart owners name $ncart->add_item ("10", 1); // (inherited functionality from cart) Bên trong các hàm của một lớp biến $this có ý nghĩa là đối tượng này. Ta phải dùng $this- >something để truy nhập đến bất kỳ biến nào hoặc hàm nào được đặt tên something trong đối tượng hiện thời. Cả bên trong lẫn bên ngoài của đối tượng ta không cần một dấu $ khi truy nhập vào các thuộc tính của một đối tượng. $ncart->owner = "chris"; // no $ $ncart->$owner = "chris"; // this is invalid because $ncart->$owner = $ncart->"" $myvar = 'owner'; $ncart->$myvar = "chris"; // this is valid because $ncart->$myvar = $ncart->owner Các hàm khởi tạolà các hàm trong một lớp và được gọi một cách tự động khi ta tạo một thể hiện mới của một lớp. Một hàm trở thành một hàm khởi tạo khi nó có cùng tên với tên của lớp. class Auto_Cart extends Cart { function Auto_Cart () { $this->add_item ("10", 1); } } Điều này định nghĩa một lớp Auto_Cart đó là một Cart thêm một hàm khởi tạo mà khởi tạo một xe chở với một phần tử thực phẩm số “10” mỗi lần một Auto_Cart được tạo với từ “new”. Các hàm khởi tạo cũng có thể đưa ra các đối số và các đối số này có thể được tuỳ chọn, nó tạo cho chúng sự thuận tiện nhiều hơn. 52 class Constructor_Cart extends Cart { function Constructor_Cart ($item = "10", $num = 1) { $this->add_item ($item, $num); } } // Shop the same old boring stuff. $default_cart = new Constructor_Cart; // Shop for real... $different_cart = new Constructor_Cart ("20", 17); Chú thích Đối với các lớp được thừa kế, hàm khởi tạo của lớp cha không được gọi một cách tự động khi hàm khởi tạo của lớp được thừa kế được gọi. 2_Các tham chiếu bên trong hàm khởi tạo Việc tạo ra các tham chiếu bên trong hàm khởi tạo có thể dẫn đến các kết quả khó hiểu. class foo { function foo($name) { // create a reference inside the global array $globalref global $globalref; $globalref[] = &$this; // set name to passed value $this->setName($name); // and put it out $this->echoName(); } function echoName() { echo "",$this->Name; } function setName($name) { $this->Name = $name; } } Chúng ta hãy cùng kiểm tra nếu có một sự khác biệt giữa $bar1 mà đã được tạo bằng cách dùng toán tử = sao chép và $bar2 mà được tạo bằng cách dùng toán tử tham chiếu =& ... $bar1 = new foo('set in constructor'); $bar1->echoName(); $globalref[0]->echoName(); /* output: set in constructor set in constructor set in constructor */ $bar2 =& new foo('set in constructor'); $bar2->echoName(); $globalref[1]->echoName(); 53 /* output: set in constructor set in constructor set in constructor */ Dường như không có sự khác biệt, nhưng trong thực tế có một điểm rất khác biệt: $bar1 và $globalref[0] đã không được tham chiếu, chúng không cùng chung biến. Điều này giải thích tại sao “new” mặc định không trả về một tham chiếu, thay vì đó nó trả về một sao chép. Chú ý: Không có sự thực hiện nào bị mất mát ( từ khi PHP4 và trên nữa sử dụng cả tham chiếu) trả lại các bản sao chép thay vì các tham chiếu. Trái ngược lại, tốt hơn hết là làm việc một cách đơn giản với các bản sao chép thay vì các tham chiếu, bởi vì việc tạo ra các tham chiếu đòi hỏi các tốn thời gian trong khi việc tạo ra các bản sao chép dường như không mất thời gian ( nếu không phải không số nào trong chúng là một mảng lớn hoặc đối tượng và một trong số chúng đã thay đổi và các số khác còn lại sau đó, tiếp đến nó sẽ chỉ ra cách dùng các tham chiếu để thay đổi chúng một cách đồng thời). Để chứng tỏ điều gì được viết ở trên chúng ta hãy xem đoạn mã dưới đây: // now we will change the name. what do you expect? // you could expect that both $bar and $globalref[0] change their names... $bar1->setName('set from outside'); // as mentioned before this is not the case. $bar1->echoName(); $globalref[0]->echoName(); /* output: set on object creation set from outside */ // let us see what is different with $bar2 and $globalref[1] $bar2->setName('set from outside'); // luckily they are not only equyl, they are thesame variable // thus $bar2->Name and $globalref[1]->Name are the same too $bar2->echoName(); $globalref[1]->echoName(); /* output: set from outside set from outside */ Một ví dụ cuối cùng, hãy cố gắng để hiểu nó: class a { function a($i) { $this->value = $i; // try to figure out why we do not need a reference here $this->b = new b($this); } function createRef() { $this->c = new b($this); } function echoValue() { echo "","class ",get_class($this),': ',$this->value; } 54 }class b { function b(&$a) { $this->a = &$a; } function echoValue() { echo "","class ",get_class($this),': ',$this->a->value; } } // try to undestand why using a simple copy here would yield // in an undesired result in the *-marked line $a =& new a(10); $a->createRef(); $a->echoValue(); $a->b->echoValue(); $a->c->echoValue(); $a->value = 11; $a->echoValue(); $a->b->echoValue(); // * $a->c->echoValue(); /* output: class a: 10 class b: 10 class b: 10 class a: 11 class b: 11 class b: 11 */ 55
File đính kèm:
- Giáo trình Apache PHP và MySQL.pdf