2009-07-31 31 views
5

Tôi có trang include.php mà tôi tải vào đầu mỗi trang của trang web của mình. Khi tôi phát triển trang web, số lượng lớp học mà tôi đang sử dụng ngày càng tăng. Vì vậy, tôi kết thúc với một cái gì đó như thế này:hiệu suất của việc tải các lớp học php và sử dụng 'mở rộng'

$db = new DB($config); 
$login = new Login($db, $config); 
$form = new Form($db, $config); 

Và danh sách này tiếp tục và bật. Tôi có hai câu hỏi về thực tiễn này:

Đầu tiên, Xem xét tôi có thể không sử dụng một lớp học tại một trang nhất định (tôi có thể không có biểu mẫu $ trên mỗi trang), mức độ thực sự quan trọng, hiệu suất- khôn ngoan, để tải lớp này mỗi khi có trang nào được tải?

Thứ hai, bạn có thể nhận thấy rằng tôi đang chuyển cá thể lớp $ db đến tất cả các lớp khác, cũng như biến $ config. Trong đoạn code php của mỗi lớp, tôi làm điều gì đó như thế này:

public $db; 
public $config; 

public function __construct($db, $config, $smarty){ 
    $this->db = $db; 
    $this->config = $config; 
} 

sau đó trong các phương pháp lớp học, tôi quyết các cơ sở dữ liệu và cấu hình tập tin với 'này' như vậy:

public function myfunction(){ 
    $this->db; 
    $this->config; 
} 

Khi cần Tôi sử dụng 'mở rộng' thay vì chuyển $ db vào lớp, giả sử mỗi lớp sử dụng db? Không chuyển $ db cho mỗi lớp bị tổn thương trong bất kỳ cách nào về hiệu suất?

Cảm ơn!

Trả lời

7

Khi nào tôi nên sử dụng 'kéo dài' thay hơn đi qua $ db đến lớp, giả sử mỗi lớp sử dụng db?

Khi có ý nghĩa - và chỉ khi nào vậy!

Bạn có ít nhất hai điều cần xem xét:

  • "class A extends B" loại phương tiện "class A **is a** B"
    • rõ ràng hơn, một Car là một MotorVehicule; a MotorVehiculeVehicule; a BusMotorVehicule; một xe đạp là tuy nhiên một Vehicule
    • , một Ball không phải là một Vehicule
    • Trong trường hợp của bạn, một Form là chắc chắn không phải là một DataBase! Cũng không phải là một Login
  • Trong PHP, một lớp chỉ có thể extendmột lớp
    • Bạn không thể có một cái gì đó là cả một Vehicule và một Animal
    • Nhưng một Carlà mộtMotorVehicule , chính nó, Vehicule:-)

Trong trường hợp của một đối tượng cơ sở dữ liệu (trong trường hợp của bạn, nó nhiều hơn một kết nối đến một DB), mosts của các lớp học của bạn sẽ không tự "là" một kết nối cơ sở dữ liệu. Vì vậy, họ không nên mở rộng lớp đó.

Tuy nhiên, họ đang sử dụng một kết nối DB (một Form "" Kết nối DB); vì vậy, họ nên có một tài sản đại diện cho kết nối DB đó. Đó là những gì bạn đang làm.


Thay vì đi qua $db cho mỗi nhà xây dựng, bạn có thể sử dụng

  • một trong hai mô hình Singleton thiết kế
  • hoặc mô hình Registry thiết kế
  • hoặc một số loại biến toàn cầu, nhưng đó là gần như cùng ... chỉ là tồi tệ hơn (không phải OOP và tất cả những điều đó)!

Nhưng chuyển đối tượng $db thật tuyệt vời để thử nghiệm đơn vị, đối tượng giả và tất cả ...
Tôi nghĩ rằng nó có thể được coi là thiết kế tiêm mẫu dependancy, btw (không chắc chắn, nhưng có vẻ như nó)


Về tải rất nhiều lớp học, những người khác đã đưa câu trả lời:

  • Sử dụng tự động load nếu bạn có thể
  • Sử dụng một bộ nhớ cache opcode, như APC, nếu bạn có thể

Cả hai đó là những gợi ý tuyệt vời mà bạn nên đi vào xem xét ;-)


Một điều cuối cùng:

Liệu đi qua $ db để mỗi lớp tổn thương dưới mọi hình thức về hiệu suất?

Có thể nó ít bit; nhưng, honnestly, ngoại trừ nếu bạn là google và có hàng triệu người dùng ... những người quan tâm?

Nếu bạn đang thực hiện một vài truy vấn DB, những truy vấn này sẽ mất rất nhiều thời gian, so với việc chuyển một tham số khác đến thậm chí cả tá phương pháp!
Vì vậy, số lượng nhỏ thời gian sử dụng qua paremeters có lẽ có thể được bỏ qua :-)

+0

Tuyệt vời và toàn diện! Cảm ơn nhiều. –

+0

Bạn được chào đón :-) Hãy vui vẻ! –

+1

Mở rộng các lớp học là một bí ẩn nhỏ đối với tôi trong một thời gian, đây là một lời giải thích tuyệt vời và đơn giản ngay lập tức làm cho nó rất rõ ràng đối với tôi khi sử dụng nó. – Kokos

4

Bạn đã thử một cái gì đó như thế này?

function __autoload($class_name) { 
require_once("includes/php/class." . $class_name . ".php"); 
} 

Vì vậy, nó chỉ tải tên lớp khi gặp phải tên lớp. (Thay đổi đường dẫn cho phù hợp với các lớp học php của bạn ... của tôi giống như class.Object.php, với tên lớp "Object").

+1

thêm vào này những gì jeyoung nói: bạn thực sự chỉ nên tải những gì bạn cần * khi * bạn cần nó có mặt. Vẫn còn một số câu hỏi chưa được trả lời trong bài đăng này (khi nào sử dụng mở rộng), có thể trích xuất tốt hơn vào các câu hỏi SO mới. –

+0

Tôi có nên đặt mã này trong tệp bao gồm của tôi hoặc trong các lớp học của tôi không? Nó sẽ không luôn luôn gặp biến, mặc dù, kể từ khi tôi nhanh chóng lớp ngay sau khi tải tập tin? Cảm ơn! –

+0

Bạn sẽ đặt mã này trong header.php của bạn (được bao gồm trong tất cả các tệp của bạn). Bạn có thể giải thích ý của bạn bằng cách khởi tạo lớp ngay sau khi tải tệp không? – Dirk

1

Tại sao không chỉ bao gồm các tệp cần được đưa vào? Ngoài ra, hãy thử để nhanh chóng chỉ những đối tượng mà bạn cần ở nơi bạn cần chúng. Vì nó là, includes.php của bạn đang thực hiện rất nhiều phiên bản mà bạn có thể không cần tất cả thời gian.

Nếu $db được chuyển làm tham chiếu, nó sẽ không ảnh hưởng đến hiệu suất. (Tôi không biết nhiều về PHP5, nhưng với PHP4 đã có một khái niệm về tài liệu tham khảo với '&' modifier.)

+0

Tôi đã luôn tự hỏi, biểu tượng dấu và (&) làm gì trong PHP? –

+2

& cung cấp cho bạn tham chiếu đến biến. Trong PHP5, bạn sẽ không bao giờ phải sử dụng điều này như một phương pháp cải thiện hiệu suất (PHP sao chép trên ghi). Ngoài ra trong các biến đối tượng PHP5 đã được tham chiếu đến đối tượng, vì vậy các đối tượng không được sao chép trừ khi bạn sử dụng 'clone'. –

2

Nếu tải và phân tích các tập tin kịch bản trở thành một nút cổ chai bạn có thể sử dụng một bộ nhớ cache bytecode như apc để tăng tốc độ phần này của vòng đời.

+0

Chính xác thì apc làm gì? –

+0

Khi PHP tải một tập lệnh, nó phải phân tích cú pháp nội dung thành mã opcodes. apc lưu trữ các opcodes này để lần sau không cần chạy trình phân tích cú pháp. Nếu bạn vô hiệu hóa việc kiểm tra chỉ số thì thậm chí có thể tránh được việc truy cập tệp (tương đối chậm). – VolkerK

1

Tôi không chắc chắn chính xác bạn muốn sử dụng thừa kế ('extends') tại đây như thế nào. Bạn có thể sử dụng nó để xác định hai trường $db$config, nhưng nếu không nó sẽ không thay đổi nhiều.

Ngoài ra, nó có thể giới hạn bạn khi bạn thực sự muốn kế thừa một cái gì đó hữu ích từ một lớp khác.

Tùy thuộc vào thiết kế của bạn, bạn có thể cân nhắc việc tạo $config toàn cầu. Có tình huống có nhiều hơn 1 cấu hình hoạt động cùng một lúc không? Nó có lẽ sẽ không là một ý tưởng tốt để giới thiệu một biến toàn cầu $db tuy nhiên. Có thể hiểu rằng bạn có thể cần nhiều hơn một kết nối cơ sở dữ liệu cùng một lúc chẳng hạn.

+0

Lý do duy nhất tôi không sử dụng $ config là toàn cầu là vì tôi nghe nói nó không an toàn. Tên người dùng và mật khẩu cơ sở dữ liệu của tôi được lưu trữ trong tệp cấu hình. Không có vấn đề bảo mật thực sự nào khi khai báo các biến toàn cầu? –

Các vấn đề liên quan