2011-09-16 20 views
9

Có lý do nào để đặt giá trị cho các biến trong hàm tạo của một lớp thay vì khi bạn khai báo chúng không? Tôi nhận ra rằng bạn không thể chuyển dữ liệu vào các biến nếu bạn cố gắng đặt chúng khi chúng được khai báo, nhưng điều gì sẽ luôn giống nhau (tôi giả sử 'luôn luôn' là một yêu cầu khó khăn để thực hiện)?Tại sao đặt các biến bên trong cấu trúc của một lớp PHP khi bạn có thể đặt chúng khi chúng được khai báo?

class variables_set_outside_constructor 
{ 
    private $admin_name = 'jeff'; 
    private $current_working_directory = get_cwd(); 

    function __construct() {} 
} 

như trái ngược với điều này:

class variables_set_inside_constructor 
{ 
    private $admin_name; 
    private $current_working_directory; 

    function __construct() 
    { 
     $this->admin_name = 'jeff'; 
     $this->current_working_directory = get_cwd(); 
    } 
} 

những ưu điểm và nhược điểm của thiết lập các giá trị trong các nhà xây dựng so với khi chúng được khai báo là gì? Tôi cũng tò mò về bất kỳ khía cạnh bất khả tri ngôn ngữ nào.

+3

Tôi không chắc tôi hiểu những gì bạn đang yêu cầu. Bạn có thể cho chúng tôi một ví dụ về mỗi kỹ thuật mà bạn đang cố gắng so sánh không? –

+1

Tôi đang làm phiền điều này bởi vì tôi là một lập trình viên có kinh nghiệm, bằng cách nào đó không bao giờ học được lý do tại sao nó sẽ là xấu để khai báo những thứ bên ngoài một nhà xây dựng. Tôi ngạc nhiên vì rất nhiều người nhảy múa quanh điểm của câu hỏi này chỉ để cho bạn biết những điều không liên quan về ví dụ của bạn. Nhưng một ví dụ tốt hơn có thể là giá trị mặc định. Giống như một trò chơi - int level = 1; thì hàm tạo có thể ghi đè lên điều này, nhưng ít nhất nó sẽ luôn có một giá trị mặc định. Ngay cả sau khi đọc điều này tôi vẫn không chắc chắn về một câu trả lời chính thức. Tôi đoán tôi sẽ chỉ tiếp tục tuyên bố trong lớp sau đó populating trên xây dựng. –

+0

Bạn có thể muốn kiểm tra lại ví dụ thứ hai của mình. (Trên thực tế, hãy kiểm tra cả hai - 'class X() {}' là cú pháp không hợp lệ. Nhưng ...) Giá trị mặc định của thuộc tính phải là chữ (hoặc có thể là hằng số), cuối cùng tôi nghe thấy. – cHao

Trả lời

2

Lý do đầu tiên: khả năng sử dụng lại.

Lý do thứ hai: Thông tin đăng nhập cho kết nối cơ sở dữ liệu của bạn không thuộc lớp cơ sở dữ liệu, điều này sẽ được xử lý trong ứng dụng của bạn. Lớp học của bạn chỉ nên biết cách chấp nhận và sử dụng chúng - không xác định chúng.

Một ví dụ điển hình là có thông tin đăng nhập khác trên development machine của bạn sau đó trên staging/live machine. Điều này ngay lập tức cho bạn thấy vấn đề với việc khai báo trong hàm tạo.


Tôi không nhận thấy nỗ lực đó là gì cho đến khi nhận xét của bạn. Tôi không được sử dụng để xem var nữa tôi đoán. May mắn thay, tôi không phải là người duy nhất. Tất nhiên tuyên bố như vậy là không thể.

+0

lý do thứ ba: Khởi tạo thành viên nhóm chỉ hoạt động với các hằng số, không phải biểu thức. 'mysqli mới ('host', 'name', 'pass', 'directory');' sẽ không bao giờ hoạt động. – hakre

3

Bạn gặp lỗi trong câu hỏi của mình. Điều này không làm việc trong một lớp học:

class foo 
{ 
    var $mysqli = new mysqli('host', 'name', 'pass', 'directory'); 
} 

Thử Demo để xem những gì không làm việc ở đây.

Vì vậy, có lẽ một (!) Lý do để viết

class foo 
{ 
    var $mysqli; 
    public function __construct() 
    { 
     $this->mysqli = new mysqli('host', 'name', 'pass', 'directory'); 
    } 
} 

là vì không có thay thế cho nó (giữa hai lựa chọn thay thế bạn đã có bằng các câu hỏi của bạn mà thôi, một cách tự nhiên. Đây là thói quen xấu horrorful để làm như vậy w/oa thiết kế tinh tế dựa trên tiêm phụ thuộc và các trừu tượng thiết kế cấp cao khác - hoặc chính xác hơn: Điều này đang làm cho mysqli phụ thuộc của foo - bao gồm cấu hình cơ sở dữ liệu).

Bên cạnh đó, vui lòng không sử dụng var, sử dụng private, protected hoặc public để thay thế.

+0

@downvoter: Hãy chia sẻ suy nghĩ của bạn. – hakre

0

Để dễ truy cập. Khai báo tất cả chúng ở một vị trí trung tâm cho phép bạn, cũng xem danh sách tất cả các biến.

Nó không phải là một vấn đề lớn nếu bạn khai báo khi nó được tạo ra nếu bạn đang ở trong một dự án solo. Nếu bạn đang làm việc với các nhóm, bạn nên hiểu theo một số tiêu chuẩn để không bị lẫn lộn.

0

Mặc dù không linh hoạt, thiết lập các biến khi bạn khai báo nó có thể hữu ích nếu bạn có kế hoạch để sử dụng một lớp mà không cần tạo một thể hiện đối với một số lý do:

class MyClass { 
    public $MyVar = 'hello'; 

    function MyFunction() { 
    return self::MyVar; 
    } 
} 

echo MyClass::MyFunction(); 
2

Bạn có thể thấy this article on Java object initializers là một số lợi ích.

Mặc dù nhiều khái niệm trong bài viết là đặc trưng cho Java và không liên quan đến PHP, bạn có thể tìm thấy một số trong những điểm thú vị:

  • Trước khi bạn sử dụng một tài sản trong một lớp học, bạn thường muốn nó được khởi tạo cho một số giá trị (trong PHP, đây không phải là một yêu cầu, nhưng trong thực tế tôi hiếm khi thấy hướng dẫn này bị vi phạm). Nếu bạn có nhiều hàm tạo thì bạn phải khởi tạo thuộc tính trong mỗi hàm tạo có nghĩa là sẽ có rất nhiều việc sao chép và dán. (PHP also has multiple contructors:)

  • Trong các lớp con Java, chỉ có hàm tạo "no-arg" cha được gọi theo mặc định, có nghĩa là bạn không thể đảm bảo rằng lớp con sẽ gọi hàm tạo "đúng". Trong PHP, vấn đề là phức tạp bởi vì bạn không thể đảm bảo rằng lớp con sẽ gọi hàm tạo của lớp cha ở tất cả. Việc khởi tạo các thuộc tính trực tiếp trong khai báo lớp cha đảm bảo rằng các thuộc tính đó luôn bắt đầu khởi tạo, ngay cả khi hàm tạo lớp con không khởi tạo chúng.

0

nó có thể giúp tìm nạp bản ghi từ cơ sở dữ liệu một lần và sử dụng lại hồ sơ. như tôi đã làm với thư viện đăng nhập tankauth.

class Welcome extends CI_Controller{ 
    public $id; 
    function __construct(){ 
     parent::__construct(); 
     $this->id = $this->tank_auth->get_user_id(); 
    } 
function index(){ $this->MyModel->get_user($this->id);} 
function admin(){ $this->MyModel->get_admin($this->id);} 
function profile(){ $this->MyModel->get_profile($this->id);} 
} 
0

Cá nhân tôi muốn khai báo biến bên trong hàm tạo do dễ quản lý chúng hơn. Nếu tôi có một lớp với tấn và tấn phương pháp, thì nó sẽ là một nỗi đau trong ** để tìm nơi biến được khai báo hoặc thậm chí tệ hơn, giả sử chúng ta nhận được yêu cầu POST, điều gì có thể xảy ra nếu tôi quên khử trùng và xác nhận bài đăng này. SQL injection ... Nếu bạn có tất cả các yêu cầu máy chủ của bạn trong constructor, bạn có thể dễ dàng tìm thấy tất cả, hãy nói tạo một phương pháp khử trùng tùy thuộc vào những gì bạn đang mong đợi và sau đó bạn sẽ được bảo đảm chống lại những cuộc tấn công.

dụ:

<?php 
    Class Example extends Core_Controllers 
    { 
     private $_var = null; 

     public function __construct(){ 

       if(isset($_POST['number'])): 
       $this->_var = $this->santizeNumber($_POST['number']); 
       else: 
       $this->_var = "Not Declared Yet"; 
       endif; 

      $this->methodToCall(); 
     } 
     } 


     public function sanitizeNumber($number){ 
       return filter_var($number, FILTER_SANITIZE_NUM_INT); 
     } 

     public function methodToCall(){ 
      echo $this->_var; 
     } 
Các vấn đề liên quan