2010-02-16 61 views
15

Tôi biết về array_walk()array_map(). Tuy nhiên khi sử dụng cựu như vậy (trên một dự án cũ) nó thất bạiCách dễ dàng để áp dụng hàm cho một mảng

array_walk($_POST, 'mysql_real_escape_string'); 

Cảnh báo: mysql_real_escape_string() hy vọng tham số 2 được tài nguyên, chuỗi nhất định.

Vì vậy, tôi đã đi với phiên bản hơi xấu xí hơn này

foreach($_POST as $key => $value) { 
    $_POST[$key] = mysql_real_escape_string($value); 
} 

Vì vậy, tại sao không phải là công việc cách đầu tiên? Cách tốt nhất để ánh xạ các giá trị của một mảng thành một hàm là gì?

+0

Liệu phiên bản xấu xí thực sự làm việc? –

+2

Phiên bản xấu xí * hoạt động *. – alex

Trả lời

28

Chức năng gọi lại được chuyển đến array_walk dự kiến ​​sẽ chấp nhận hai tham số, một cho giá trị và một cho khóa:

Thông thường, funcname có hai tham số. Giá trị tham số mảng là giá trị đầu tiên và khóa/chỉ mục thứ hai.

Nhưng mysql_real_escape_string hy vọng thông số thứ hai là tài nguyên. Đó là lý do bạn nhận được lỗi đó.

Sử dụng array_map thay vào đó, nó chỉ mất giá trị của từng hạng mục và vượt qua nó để chức năng gọi lại đưa ra:

array_map('mysql_real_escape_string', $_POST); 

Tham số thứ hai sẽ được bỏ qua và do đó cuối cùng đã mở kết nối được sử dụng.

Nếu bạn cần chuyển tham số thứ hai, bạn cần phải thực hiện lệnh gọi hàm trong một hàm khác, ví dụ: một anonymous function:

array_map(function($string) use ($link) { return mysql_real_escape_string($string, $link); }, $_POST); 
+3

'array_map()' cũng là một lựa chọn tốt hơn vì nó không sửa đổi mảng ban đầu, nó trả về một mảng mới sau khi hàm được áp dụng. – kapa

2

Đó là vì mysql_real_escape_string đang được cung cấp hai tham số, cả hai chuỗi.

http://php.net/manual/en/function.mysql-real-escape-string.php

http://www.phpbuilder.com/manual/en/function.array-map.php:

array_map() trả về một mảng chứa tất cả các yếu tố của arr1 sau khi áp dụng các hàm callback cho mỗi người. Số lượng các thông số rằng hàm callback chấp nhận phải phù hợp với số lượng mảng truyền cho array_map()

bạn có thể làm

function myescape($val) 
{ 
    return mysql_real_escape_string($val); 
} 

... sau đó

array_walk($_POST, 'myescape'); 
+0

Vì vậy 'mảng_walk()' sẽ ánh xạ mọi giá trị mảng cho tất cả các tham số của hàm? Không phải là một chút .. * lạ *? Bất kỳ cách nào tôi có thể nói "Xin vui lòng chỉ param đầu tiên"? – alex

+0

Câu trả lời cho câu hỏi đầu tiên là KHÔNG. –

+0

Tôi nghĩ myescape thiếu đối số thứ 2 ở đây: $ key –

2

http://php.net/manual/en/function.array-walk.php nói rằng array_walk sẽ gọi hàm với 2 đối số, giá trị và chìa khóa.Bạn nên viết một hàm mới để bọc mysql_real_escape_string. Một cái gì đó như:

function wrapper($val, $key){ 
    return mysql_real_escape_string($val); 
} 

Và sau đó:

array_walk($_POST, 'wrapper'); 

Xin lỗi nếu PHP của tôi là không đúng, nhưng tôi nghĩ rằng bạn sẽ nắm bắt được ý tưởng chung.

+1

Ý bạn là, đối số thứ 2 cho 'array_walk()' phải là ''wrapper''. – alex

2

mysql_real_escape_string() sẽ không hoạt động trừ khi bạn đã thực hiện kết nối mysql trước. Lý do thật tuyệt vời là nó sẽ thoát khỏi các nhân vật theo cách phù hợp với loại bàn. Đối số thứ hai [tùy chọn] là tham chiếu đến kết nối mysql.

$_POST luôn được thiết lập là key->value. Vì vậy, bạn gọi array_walk gọi mysql_real_escape_string(value, key). Lưu ý đối số thứ hai không phải là tham chiếu.

Đó là lý do tại sao nó không hoạt động. Có một số giải pháp đã được đề cập ở trên.

-2

Tôi gặp sự cố khi sử dụng câu trả lời được chấp nhận vì nó gây ra lỗi cho tôi vì lý do tôi không thể làm việc. Vì vậy, đối với bất cứ ai gặp rắc rối với array_walk hoặc array_map tôi thấy điều này để làm việc.

foreach($_POST as $pk => $pv) $_POST[$pk] = mysql_real_escape_string($pv); 
+0

Bạn đã đặt câu hỏi về vấn đề là gì? Bằng cách này câu trả lời này đơn giản là truyền bá một huyền thoại rằng có một số loại vấn đề với 'array_map()'. -1 – kapa

+0

@ bažmegakapa Điều này không lan truyền bất kỳ huyền thoại nào. Điều này chỉ là cung cấp một giải pháp thay thế, đơn giản hơn để hiểu cho những người ít quen thuộc hơn với các chức năng của php. OP yêu cầu một cách dễ dàng để áp dụng một chức năng cho một mảng, mà điều này không ... Bạn thực sự đang nói về điều gì? –

+0

Tôi thậm chí không đề cập rằng cùng một mã bạn đã đăng là câu trả lời đã có trong câu hỏi ... – kapa

1

Tôi biết OP hỏi để gọi một chức năng, tuy nhiên trong trường hợp bạn không thực sự cần phải gọi một chức năng bạn có thể xác định một anonymous one:

$ids = [1,2,3]; 
array_walk($ids,function(&$id){$id += 1000;}); 
Các vấn đề liên quan