2009-11-22 34 views
14

Tôi muốn kích hoạt một hàm dựa trên biến.PHP: Biến trong tên hàm

function sound_dog() { return 'woof'; } 
function sound_cow() { return 'moo'; } 

$animal = 'cow'; 
print sound_{$animal}(); *

Dòng * là dòng không chính xác.

Tôi đã thực hiện việc này trước đây, nhưng tôi không thể tìm thấy. Tôi biết về các vấn đề bảo mật tiềm ẩn, v.v.

Bất kỳ ai? Cảm ơn nhiều.

Trả lời

19

Bạn có thể làm điều đó, nhưng không phải không có suy chuỗi đầu tiên:

$animfunc = 'sound_' . $animal; 
print $animfunc(); 

Hoặc, bỏ qua tạm thời biến với call_user_func():

call_user_func('sound_' . $animal); 
+0

Cảm ơn một nhóm. Bạn đã cứu tôi rất nhiều kích thích! – LibraryThingTim

+0

Đây là một phương pháp hấp dẫn. Nó có phải là một nguy cơ bảo mật để cung cấp cho một truy cập trực tiếp biến REQUEST này? Nếu vậy, các biện pháp có thể được thực hiện để ngăn chặn nó? Có lẽ một danh sách các chức năng mà bạn chỉ muốn cung cấp quyền truy cập vào, và một kiểm tra chống lại danh sách này khi các REQUEST var của tên này là gặp phải? –

+0

Bạn không được cấp quyền truy cập trực tiếp REQUEST (đọc: LUÔN vệ sinh đầu vào của người dùng). Một bảng điều phối dọc theo dòng câu trả lời của Greg Hewgill có lẽ là giải pháp tốt nhất.Bạn có thể kiểm tra tính hợp lệ của đầu vào YÊU CẦU thông qua array_key_exists(), chỉ cần chắc chắn rằng bạn trích dẫn các giá trị (sound_dog -> 'sound_dog') hoặc nó sẽ ném một thông báo. – scribble

1

Bạn nên tự hỏi mình tại sao bạn cần phải làm điều này, có lẽ bạn cần phải cấu trúc lại mã của bạn để một cái gì đó như sau:

function animal_sound($type){ 
    $animals=array(); 
    $animals['dog'] = "woof"; 
    $animals['cow'] = "moo"; 
    return $animals[$type]; 
} 

$animal = "cow"; 
print animal_sound($animal); 
+1

Tôi thấy phương pháp của bạn kém sạch hơn nhiều. Đây là suy nghĩ của C. –

+0

1 chức năng có thực hiện tương tự như 2 chức năng? – Sam152

+4

C suy nghĩ? Sử dụng bảng băm? Giống như tư duy mã duy trì được. – recursive

15

Bạn có thể làm điều đó như thế này:

$animal = 'cow'; 
$sounder = "sound_$animal"; 
print ${sounder}(); 

Tuy nhiên , một cách tốt hơn là sử dụng một mảng:

$sounds = array('dog' => sound_dog, 'cow' => sound_cow); 

$animal = 'cow'; 
print $sounds[$animal](); 

Một trong những lợi thế của phương pháp mảng là khi bạn quay lại mã của bạn tháng sau và tự hỏi "gee, đây là chức năng sound_cow được sử dụng?" bạn có thể trả lời câu hỏi đó bằng một tìm kiếm văn bản đơn giản thay vì phải tuân theo tất cả logic tạo ra tên hàm biến đổi khi đang bay.

0

Bạn có thể sử dụng $this->self:: cho các hàm-lớp. Ví dụ được cung cấp bên dưới với tham số đầu vào chức năng.

$var = 'some_class_function'; 
call_user_func(array($this, $var), $inputValue); 
// equivalent to: $this->some_class_function($inputValue); 
0

Bạn có thể sử dụng dấu ngoặc nhọn để tạo tên hàm của mình. Không chắc chắn về khả năng tương thích ngược, nhưng ít nhất là PHP 7+ có thể làm điều đó.

Đây là mã của tôi khi sử dụng Carbon để thêm hoặc trừ đi thời gian dựa trên người dùng loại lựa chọn (của 'thêm' hoặc 'phụ'):

$type = $this->date->calculation_type; // 'add' or 'sub' 

$result = $this->contactFields[$this->date->{'base_date_field'}] 
        ->{$type.'Years'}($this->date->{'calculation_years'}) 
        ->{$type.'Months'}($this->date->{'calculation_months'}) 
        ->{$type.'Weeks'}($this->date->{'calculation_weeks'}) 
        ->{$type.'Days'}($this->date->{'calculation_days'}); 

Phần quan trọng ở đây là {$type.'someString'} phần. Điều này sẽ tạo ra tên hàm trước khi thực hiện nó. Vì vậy, trong trường hợp đầu tiên nếu người dùng đã chọn 'thêm', {$type.'Years'} sẽ trở thành addYears.

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