2017-08-24 15 views
8

Tôi vừa mới được giới thiệu khái niệm về biến động trong PHP. Đối với tôi, có vẻ như việc sử dụng các biến động trong một chương trình sẽ gây khó khăn cho việc đọc/theo dõi.Tại sao sử dụng biến động (biến số biến) trong PHP hoặc các ngôn ngữ khác

Bất cứ ai có thể giải thích cho tôi những lợi ích và/hoặc chia sẻ một ví dụ thực tế đơn giản trong thực tế khi có thể cần một biến động trong PHP?

Nếu bạn tự hỏi điều gì biến động là gì và làm thế nào họ làm việc kiểm tra this question

+5

Chúng thường được gọi là biến số biến; và chỉ vì chúng tồn tại, không có nghĩa là bạn phải sử dụng chúng ... thường tôi khuyên bạn không nên sử dụng chúng, bởi vì luôn luôn có cách thay thế tốt hơn –

+0

Dường như với tôi cũng rất khó đọc/theo dõi . –

+0

Dựa trên rất nhiều câu hỏi ở đây, nơi mọi người đang cố gắng tìm ra cách sử dụng các biến biến, họ thường nên đặt tên cho các khóa mảng thay vì tạo các biến riêng biệt. –

Trả lời

6

Tôi đã bỏ phiếu để đóng câu hỏi này (bỏ phiếu kể từ khi rút lại) trên cơ sở của nó là chủ quan, nhưng suy đi tính lại, tôi nghĩ rằng tôi có thể đưa ra một câu trả lời khách quan.

Tên biến tĩnh là một chuỗi các ký tự, đại diện cho mã thông báo mà động cơ cơ bản sử dụng làm nhãn để xác định giá trị biến đại diện (mô tả của rất rất layperson).

"Chuỗi ký tự" là một chuỗi. Một chuỗi là một biểu thức đại diện cho một chuỗi. Vì vậy, từ đó nó đứng lên lý do rằng bất kỳ biểu hiện đại diện cho một chuỗi nên được tốt, đủ để đại diện cho các mã thông báo đề cập đến một biến. Và chính biểu thức đó có thể được gán cho một biến, và từ đó, một biến có tên biến động.

Nhưng đây không phải là những gì bạn đã hỏi. Bạn đã hỏi: tại sao?

Nó không dành cho người triển khai ngôn ngữ để trả lời các câu hỏi như vậy. Đó là công việc của họ để cung cấp một giao diện lập trình thống nhất và có thể dự đoán được, thông qua ngôn ngữ của họ. Đó là đồng phục để có thể trình bày chuỗi ký tự thông qua một biểu thức mà lần lượt có thể được biểu thị bằng một biến. Công việc hoàn thành.

Chủ quan, tôi có khả năng có thể thấy nơi một số dữ liệu được nhập từ nguồn bên ngoài và thậm chí lược đồ dữ liệu là động. Người ta có thể muốn đại diện cho rằng trong một số loại thời trang đối tượng chung chung, và nó dẫn từ đó rằng tên của các thuộc tính của đối tượng cũng có thể được năng động. Có hay không điều này có thể là một cách tiếp cận tốt cho vấn đề ở bàn tay là hoàn toàn chủ quan, và theo đánh giá của nhà phát triển, và của các đồng nghiệp của họ trong quá trình xem xét mã.

Ví dụ khác có thể là bạn đã thừa hưởng một số mã spaghetti kém chất lượng khi "cần phải" và sử dụng đặt tên động - vì bất kỳ lý do gì - có thể là một cách tiếp cận tốt.

gánh nặng của PHP kết thúc khi cung cấp cơ chế viết mã; nó không nói đến chất lượng của thiết kế của mã đã nói. Đó là xem xét mã là gì.

+1

Câu trả lời hay! Cảm ơn bạn đã dành thời gian giải thích. Bạn có một số điểm tuyệt vời! – ScottyG

+1

Sẽ tốt hơn nếu bạn không tự động đóng câu hỏi khi/nếu câu hỏi này tạo ra một câu trả lời thú vị. –

4

A variable variable, chỉ là một dạng khác là reflection. Về cơ bản, bạn hỏi "Tại sao bạn lại muốn thay đổi một biến, nếu bạn không biết nó trước khi chạy".

Mặc dù về mặt kỹ thuật không giống nhau, bạn có thể thấy variable variable là một loại khác nhau của hash table (hoặc array trong php). Hầu hết variable variables có thể được viết lại dưới dạng hash table và bạn sẽ không ngạc nhiên. Nhưng nếu bạn cần phải làm việc với một biến trước và sau khi chạy, thì hash table thậm chí có thể còn tồi tệ hơn để làm việc.

Trường hợp sử dụng đơn giản có thể là cài đặt có thể được thay đổi bởi người dùng. Hãy ghi nhớ ví dụ sau là không an toàn như vậy, nhưng chứng tỏ đó là mục đích.

<?php 
/* 
Simple way, if you have a limited amount of settings 
*/ 
$settings = array(); 
$settings["allowAccess"] = 1; 
$settings["allowModify"] = 1; 
$settings["allowDelete"] = 0; 

if ($result = $mysqli->query("SELECT `allowAccess`, `allowModify`, `allowDelete` FROM `user_settings` LIMIT 1")) 
{ 
    $row = $result->fetch_array(MYSQLI_ASSOC); 
    $settings["allowAccess"] = $row["allowAccess"]; 
    $settings["allowModify"] = $row["allowModify"]; 
    $settings["allowDelete"] = $row["allowDelete"]; 
} 

/* 
Now consider you have a thousand settings and you dont want to write out every setting manually. 
*/ 
if ($result = $mysqli->query("SELECT * FROM `user_settings` LIMIT 1")) 
{ 
    $row = $result->fetch_array(MYSQLI_ASSOC); 
    foreach($row as $key => $val) { 
     $settings[$key] = $val; 
    } 
} 

/* 
Both options work, but everytime you want to use a setting you have to use something like below 
*/ 

if ($settings["allowAccess"] && $settings["allowModify"] && $settings["allowDelete"]) { 
    unlink($somefile); 
} 

/* 
Perhaps you would rather write 
*/ 

if ($allowAccess && $allowModify && $allowDelete) { 
    unlink($somefile); 
} 

/* 
Then you can use 
*/ 
if ($result = $mysqli->query("SELECT * FROM `user_settings` LIMIT 1")) 
{ 
    $row = $result->fetch_array(MYSQLI_ASSOC); 
    foreach($row as $key => $val) { 
     //if you use extract, all columns are extracted, unless you drop them first. But perhaps you need those for something else. 
     //now I extract the columns that start with allow and keep the columns like id, created, modified, etc. without the need to specify each column manually, which makes it easier if you ever decide to add another setting column. You don't need to update this part of the code. 
     if (substr($key,0,5)=='allow') { 
      $$key = $val; //$key = 'allowAccess', $$key == $allowAccess = $val; 
     } 
    } 
} 
?> 

Đây chỉ là một ví dụ, tôi tìm thấy một ví dụ khác trong số XHTML sanitizer for MediaWiki bởi Brion Vibber. Ông sử dụng rất nhiều mảng trong mã của mình và tại một thời điểm, ông cần phải lật tất cả chúng. Anh ấy đã sử dụng mã bên dưới:

<?php 
$vars = array('htmlpairs', 'htmlsingle', 'htmlsingleonly', 'htmlnest', 'tabletags', 
       'htmllist', 'listtags', 'htmlsingleallowed', 'htmlelements'); 
foreach ($vars as $var) { 
    $$var = array_flip($$var); 
} 

?> 

Bây giờ rõ ràng là anh ấy có thể viết mã bên dưới, nhưng thực sự dễ đọc hơn?

<?php         
$htmlpairs = array_flip($htmlpairs); 
$htmlsingle = array_flip($htmlsingle); 
$htmlsingleonly = array_flip($htmlsingleonly); 
$htmlnest = array_flip($htmlnest); 
$tabletags = array_flip($tabletags); 
$htmllist = array_flip($htmllist); 
$listtags = array_flip($listtags); 
$htmlsingleallowed = array_flip($htmlsingleallowed); 
$htmlelements = array_flip($htmlelements); 
?> 

Trường hợp nào cũng giới thiệu trường hợp sử dụng khác: Nếu tôi muốn tự động quyết định mảng nào sẽ lật? Theo cách variable variable, tôi chỉ có thể đẩy các mục vào mảng và lật chúng khi thời gian đến, theo cách "bình thường", tôi sẽ cần switch hoặc if để lặp qua mảng và sau đó thêm từng tùy chọn theo cách thủ công.

+0

Ví dụ thú vị. Nó dẫn tôi đến một câu hỏi khác mặc dù, tại sao một trong những sẽ sử dụng một mảng lật? – ScottyG

+1

Tôi đã sử dụng nó trong [câu trả lời này] (https://stackoverflow.com/a/16521079/434949) để so sánh sự tương đồng một phần của hai chuỗi trong PHP. Về cơ bản bạn sử dụng nó khi bạn phải kiểm tra rất nhiều lần nếu một mảng chứa một giá trị nhất định. Bằng cách lật nó một lần, bạn có thể sử dụng 'array_key_exists' thay vì liên tục lặp lại toàn bộ mảng để xem nó có chứa giá trị hay không. Nhưng mặc dù ví dụ này sử dụng 'array_flip', bạn có thể sử dụng' biến biến' khi bạn muốn làm điều gì đó với nhiều biến, hoặc khi bạn muốn gán động các biến mà bạn muốn thực hiện. –

+0

'foreach ($ row as $ key => $ val) {$$ var = array_flip ($$ var); } 'đơn giản hơn là' trích xuất ($ row) '? – symcbean

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