Khi nào thì eval ác trong php?


84

Trong tất cả những năm tôi đã phát triển php, tôi luôn nghe nói rằng việc sử dụng eval()là xấu.

Xem xét đoạn mã sau, sẽ hợp lý khi sử dụng tùy chọn thứ hai (và thanh lịch hơn)? Nếu không, tại sao?

// $type is the result of an SQL statement
// e.g. SHOW COLUMNS FROM a_table LIKE 'a_column';
// hence you can be pretty sure about the consistency
// of your string
$type = "enum('a','b','c')";

// possibility one
$type_1 = preg_replace('#^enum\s*\(\s*\'|\'\s*\)\s*$#', '', $type);
$result = preg_split('#\'\s*,\s*\'#', $type_1);

// possibility two
eval('$result = '.preg_replace('#^enum#','array', $type).';');

2
eval LUÔN LUÔN xấu xa, luôn có cách tốt hơn để viết mã, đặc biệt là kể từ khi PHP giới thiệu các hàm ẩn danh. Trong trường hợp này, tôi sẽ sử dụng$result = array(); preg_replace_callback('#^enum\s*\(\s*\'|\'\s*\)\s*$#', function($m) use($result) { $result[] = $m[1]; }, $type);
Geoffrey

Vâng, thành thật mà nói, tôi nghĩ vấn đề chính của php không phải là bản thân ngôn ngữ mà là con người, những người sử dụng nó. Ba câu trả lời đúng cho câu hỏi này (của thomasrutter, của braincracking và của tôi) đều nhận được sự phản đối mà không ai có thể chống lại chúng. Mặt một tuyên bố câu trả lời khác rằng "Đôi khi eval () là chỉ / giải pháp đúng" không có ví dụ hoặc giải thích và được đầu bình chọn cho nó ...
Francois Bourgeois

Câu trả lời:


133

Tôi sẽ thận trọng khi gọi eval () thuần ác. Đánh giá động là một công cụ mạnh mẽ và đôi khi có thể là một cứu cánh. Với eval (), người ta có thể khắc phục những thiếu sót của PHP (xem bên dưới).

Các vấn đề chính với eval () là:

  • Đầu vào tiềm ẩn không an toàn. Truyền một tham số không đáng tin cậy là một cách để thất bại. Thường không phải là một nhiệm vụ tầm thường để đảm bảo rằng một tham số (hoặc một phần của nó) được hoàn toàn tin cậy.
  • Khéo léo. Sử dụng eval () làm cho mã thông minh, do đó khó theo dõi hơn. Trích lời Brian Kernighan " Gỡ lỗi khó gấp đôi việc viết mã ngay từ đầu. Do đó, nếu bạn viết mã một cách khéo léo nhất có thể, theo định nghĩa, bạn không đủ thông minh để gỡ lỗi "

Vấn đề chính với việc sử dụng eval () thực tế chỉ là một:

  • Các nhà phát triển thiếu kinh nghiệm sử dụng nó mà không có đủ sự cân nhắc.

Theo nguyên tắc chung, tôi có xu hướng làm theo điều này:

  1. Đôi khi eval () là giải pháp duy nhất / đúng.
  2. Đối với hầu hết các trường hợp, người ta nên thử một cái gì đó khác.
  3. Nếu không chắc chắn, hãy chuyển đến 2.
  4. Khác, rất, rất cẩn thận.

4
Điều này có thể được cấu trúc lại để tránh eval (), đặc biệt nếu $ className được đưa vào danh sách trắng, nó phải có để giải trí cho việc sử dụng eval (). Tuy nhiên, tin tốt là kể từ 5.3, $ foo :: bar () là hợp lệ.
rojoca

@rojoca: Bạn có thể cho chúng tôi ví dụ về cách thực hiện mà không có eval () trong PHP 5.2 được không?
Michał Rudnicki

30
Tôi không chắc liệu nó có được tính là eval hay không, nhưng $ result = call_user_func (array ('Foo', 'bar')); hoạt động như một sự quyến rũ.
Ionuț G. Stan

3
Điểm tốt về sự khôn lanh - trong ví dụ (đơn giản) của bạn, một biến bật ra "không biết từ đâu". Nếu mã trở nên phức tạp hơn một chút, chúc may mắn cho người tiếp theo nhìn vào mã và cố gắng đuổi theo biến đó xuống (ở đó, làm điều đó, tất cả những gì tôi nhận được là một cơn đau đầu và chiếc áo phông tệ hại này).
Piskvor rời tòa nhà

Đầu vào không an toàn là điều có thể tránh được
thepowerlies

40

eval là ác khi chỉ có một khả năng nhỏ nhất là userinput được đưa vào chuỗi được đánh giá. Khi bạn thực hiện đánh giá mà không có nội dung đến từ người dùng, bạn nên an toàn.

Tuy nhiên, bạn nên suy nghĩ ít nhất hai lần trước khi sử dụng eval, nó trông có vẻ đơn giản nhưng với việc xử lý lỗi (xem bình luận của VBAssassins), khả năng gỡ lỗi, v.v., nó không còn đơn giản nữa.

Vì vậy, như một quy tắc chung: Hãy quên nó đi. Khi eval là câu trả lời, bạn chắc chắn đang đặt câu hỏi sai! ;-)


6
Đôi khi đánh giá LÀ câu trả lời. Chúng tôi làm việc trên ứng dụng trò chơi trực tuyến và rất khó tránh khỏi việc trốn tránh ở đó vì mối quan hệ rất phức tạp giữa các thực thể ... nhưng IMHO trong 90% trường hợp đánh giá không phải là câu trả lời.
Jet

19
Tôi thực sự tò mò muốn xem một tình huống mà CHỈ đánh giá là câu trả lời.
Ionuț G. Stan

2
@Ionut G. Stan Kích hoạt tùy chỉnh được lưu trữ trong cơ sở dữ liệu cho các đối tượng / thực thể?
Kuroki Kaze

8
Tôi không thực sự mua rằng bất kỳ cái nào trong số đó đều là cách sử dụng hợp lý của eval (). Trong mỗi trường hợp, ít nhất vẫn có thể thực hiện điều tương tự mà không sử dụng eval (). Nó không giống như PHP bị tê liệt nếu không có eval (). Granted, eval () là một phím tắt trong những trường hợp như thế này, nhưng nó vẫn làm cho đường dẫn mã của bạn khó theo dõi hơn một chút và các vấn đề khó gỡ lỗi hơn một chút. Đó là ý kiến ​​của tôi.
thomasrutter

4
@Christian: Trước tiên, bạn nên viết một ví dụ (sử dụng pastebin.com và dán liên kết vào đây), nơi bạn cho rằng việc tránh sử dụng eval()là không thể, đây là cách tiếp cận tốt hơn. Nhiều người nói eval()là không thể tránh khỏi trong một số trường hợp, nhưng họ không đề cập đến bất kỳ ví dụ cụ thể nào mà chúng ta có thể tranh luận - theo cách này cuộc tranh luận này không có ý nghĩa. Vì vậy, xin người nói eval()là tất yếu, chứng minh điều đó trước!
Sk8erPeter

18

eval () luôn ác như nhau.

"Khi nào thì eval () không phải là ác?" là câu hỏi sai để hỏi theo ý kiến ​​của tôi, vì nó dường như ngụ ý rằng những hạn chế khi sử dụng eval () biến mất một cách kỳ diệu trong một số ngữ cảnh.

Sử dụng eval () nói chung là một ý tưởng tồi vì nó làm giảm khả năng đọc của mã, khả năng bạn dự đoán đường dẫn mã (và các tác động bảo mật có thể có của điều đó) trước thời gian chạy và do đó khả năng gỡ lỗi mã. Việc sử dụng eval () cũng có thể ngăn mã được đánh giá và mã xung quanh nó được tối ưu hóa bằng bộ đệm opcode như Zend Opcache được tích hợp vào PHP 5.5 trở lên hoặc bằng trình biên dịch JIT chẳng hạn như trong HHVM.

Hơn nữa, không có trường hợp nào là hoàn toàn cần thiết phải sử dụng eval () - PHP là một ngôn ngữ lập trình hoàn toàn có khả năng không có nó.

Việc bạn có thực sự coi đây là những tệ nạn hay không hay bạn có thể tự biện minh cho việc sử dụng eval () trong một số trường hợp là tùy thuộc vào bạn. Đối với một số người, tệ nạn quá lớn để có thể biện minh cho nó, và đối với những người khác, eval () là một phím tắt tiện dụng.

Tuy nhiên, nếu bạn thấy eval () là ác, thì đó là ác luôn. Tùy thuộc vào ngữ cảnh mà nó không mất đi sự xấu xa một cách kỳ diệu.


1
Bạn thực sự là một lập trình viên.
Christian

1
"Hơn nữa, không có trường hợp nào là hoàn toàn cần thiết phải sử dụng eval ()" - Còn nếu tôi muốn thực thi mã mà tôi đã lưu trữ trong cơ sở dữ liệu, theo ví dụ được đưa ra trong tài liệu PHP thì sao?
Yarin

4
Vì vậy, tôi muốn nói rằng việc lưu trữ mã PHP trong cơ sở dữ liệu là xấu như nhau và không cần thiết như nhau. Bất cứ điều gì bạn muốn đạt được, có nhiều cách khác để làm điều đó ngoài việc lưu trữ PHP trong cơ sở dữ liệu hoặc sử dụng eval (). Làm điều đó nếu bạn muốn, và nếu đó là một phím tắt hữu ích cho bạn, nhưng nếu bạn coi eval () là ác, thì có lẽ bạn cũng phải coi việc lưu trữ PHP trong cơ sở dữ liệu là xấu.
thomasrutter

12
Nó thêm một vectơ tấn công khác - một SQL injection sau đó cũng có thể chạy mã PHP tùy ý trên máy chủ web. Nó yêu cầu sử dụng eval (). Nó không thể được tối ưu hóa bằng bộ nhớ đệm bytecode. Nó vi phạm nguyên tắc phân tách mã và dữ liệu của bạn. Nó có thể làm cho ứng dụng của bạn ít di động hơn - để cập nhật / sửa lỗi PHP, bạn cũng phải cập nhật cơ sở dữ liệu.
thomasrutter

3
Tôi sẽ nói rằng nếu điều gì đó chỉ có thể đạt được thông qua việc sử dụng eval, thì có thể tốt để xem xét lại việc làm điều đó. Tự động tạo các lớp trong thời gian chạy có vẻ như là một ý tưởng tồi. Tại sao không sử dụng một số tạo mã và tạo mã xác định chúng trước thời hạn?
thomasrutter

15

Trong trường hợp này, eval có thể đủ an toàn, miễn là người dùng không bao giờ có thể tạo các cột tùy ý trong bảng.

Nó không thực sự thanh lịch hơn nữa. Về cơ bản đây là một vấn đề phân tích cú pháp văn bản và việc lạm dụng trình phân tích cú pháp của PHP để xử lý có vẻ hơi khó. Nếu bạn muốn lạm dụng các tính năng ngôn ngữ, tại sao không lạm dụng trình phân tích cú pháp JSON? Ít nhất với trình phân tích cú pháp JSON, không có khả năng chèn mã.

$json = str_replace(array(
    'enum', '(', ')', "'"), array)
    '',     '[', ']', "'"), $type);
$result = json_decode($json);

Một biểu thức chính quy có lẽ là cách rõ ràng nhất. Bạn có thể sử dụng một biểu thức chính quy để trích xuất tất cả các giá trị từ chuỗi này:

$extract_regex = '/
    (?<=,|enum\()   # Match strings that follow either a comma, or the string "enum("...
    \'      # ...then the opening quote mark...
    (.*?)       # ...and capture anything...
    \'      # ...up to the closing quote mark...
    /x';
preg_match_all($extract_regex, $type, $matches);
$result = $matches[1];

1
mặc dù điều này không trả lời câu hỏi cho mỗi gia nhập, đây là một câu trả lời rất tốt cho câu hỏi: điều gì sẽ là cách tốt nhất để phân tích một enum () ... cảm ơn bạn;)
Pierre mùa xuân

13

eval() là chậm, nhưng tôi sẽ không gọi nó là ác.

Việc chúng ta sử dụng nó không tốt có thể dẫn đến việc tiêm mã và trở nên xấu xa.

Một ví dụ đơn giản:

$_GET = 'echo 5 + 5 * 2;';
eval($_GET); // 15

Một ví dụ có hại:

$_GET = 'system("reboot");';
eval($_GET); // oops

Tôi khuyên bạn không nên sử dụng eval()nhưng nếu bạn làm vậy, hãy đảm bảo rằng bạn xác thực / lập danh sách trắng tất cả đầu vào.


12

Khi bạn đang sử dụng dữ liệu nước ngoài (chẳng hạn như đầu vào của người dùng) bên trong đánh giá.

Trong ví dụ của bạn ở trên, đây không phải là một vấn đề.


7

tôi sẽ ăn cắp nội dung một cách trắng trợn ở đây:

  1. Đánh giá theo bản chất của nó luôn luôn là một mối quan tâm bảo mật.

  2. Bên cạnh những lo ngại về bảo mật, đánh giá cũng có vấn đề là cực kỳ chậm. Trong thử nghiệm của tôi trên PHP 4.3.10, nó chậm hơn 10 lần so với mã bình thường và chậm hơn 28 lần trên PHP 5.1 beta1.

blog.joshuaeichorn.com: using-eval-in-php


5

eval()luôn luôn ác.

  • vì lý do an ninh
  • vì lý do hiệu suất
  • vì lý do dễ đọc / tái sử dụng
  • vì lý do IDE / công cụ
  • vì lý do gỡ lỗi
  • luôn có một cách tốt hơn

@bracketworks: Nhưng bạn đã nhầm - tất cả những vấn đề liên quan này không biến mất một cách kỳ diệu trong một số tình huống. Tại sao họ phải? Lấy ví dụ về hiệu suất: Bạn có thực sự nghĩ rằng trình thông dịch sẽ thực thi hàm eval () cực kỳ chậm với tốc độ tăng lên chỉ vì bạn đã sử dụng nó theo một cách thần bí "không phải là ác" nào đó không? Hay việc gỡ lỗi từng bước sẽ hoạt động bên trong mệnh đề eval của bạn vào một ngày may mắn nào đó?
Francois Bourgeois

3
Thành thật mà nói, tôi nghĩ câu trả lời của @ MichałRudnicki nói tốt nhất. Đừng hiểu sai ý tôi, bất cứ khi nào tôi hỏi ( bản thân ) một câu hỏi, và câu trả lời là eval(), tôi sẽ ngay lập tức cho rằng tôi đã đặt câu hỏi sai; hiếm khi nó là câu trả lời "đúng", nhưng đối với trạng thái chăn, nó luôn luôn là xấu xa đơn giản là không chính xác.
Dan Lugg

nếu tôi muốn lưu mã trong cơ sở dữ liệu? làm thế nào tôi có thể thực hiện nó?
Konstantin XFlash Stratigenas

@KonstantinXFlashStratigenas Bạn nên tự hỏi mình tại sao lại lưu trữ mã thực thi trong cơ sở dữ liệu. Cơ sở dữ liệu dành cho dữ liệu do mã của bạn - không phải mã của bạn. Ít nhất, bạn đang tăng các vectơ tấn công.
Jack B

4

Tôi cũng sẽ cân nhắc những người duy trì mã của bạn.

eval () không phải là giá vẽ để chỉ cần nhìn và biết điều gì sẽ xảy ra, ví dụ của bạn không quá tệ, nhưng ở những nơi khác, nó có thể là một cơn ác mộng.


4

Cá nhân tôi nghĩ rằng đoạn mã đó vẫn khá tệ vì bạn không bình luận về những gì nó đang làm. Nó cũng không kiểm tra tính hợp lệ của đầu vào, khiến nó rất dễ hỏng.

Tôi cũng cảm thấy rằng, vì 95% (hoặc nhiều hơn) việc sử dụng eval là nguy hiểm, nên việc tiết kiệm thời gian tiềm năng nhỏ mà nó có thể cung cấp trong các trường hợp khác không đáng để bạn bỏ qua việc sử dụng nó. Thêm vào đó, sau này bạn sẽ phải giải thích cho tay sai của mình tại sao việc sử dụng eval của bạn là tốt và của chúng là xấu.

Và, tất nhiên, PHP của bạn trông giống như Perl;)

Có hai vấn đề chính với eval (), (như một kịch bản "tấn công tiêm"):

1) Nó có thể gây hại 2) Nó có thể chỉ bị sập

và một thứ mang tính xã hội hơn là kỹ thuật:

3) Nó sẽ cám dỗ mọi người sử dụng nó một cách không thích hợp như một lối tắt ở những nơi khác

Trong trường hợp đầu tiên, bạn gặp rủi ro (hiển nhiên, không phải khi bạn đang đánh giá một chuỗi đã biết) khi thực thi mã tùy ý. Tuy nhiên, đầu vào của bạn có thể không được xác định hoặc cố định như bạn nghĩ.

Nhiều khả năng (trong trường hợp này) bạn sẽ chỉ gặp sự cố và chuỗi của bạn sẽ kết thúc với một thông báo lỗi vô cớ. IMHO, tất cả mã phải lỗi càng gọn gàng càng tốt, lỗi mà nó sẽ tạo ra một ngoại lệ (là dạng lỗi dễ xử lý nhất).

Tôi gợi ý rằng, trong ví dụ này, bạn đang viết mã theo cách ngẫu nhiên chứ không phải mã theo hành vi. Có, câu lệnh SQL enum (và bạn có chắc là trường đó là enum không? - bạn đã gọi đúng trường của bảng bên phải của phiên bản cơ sở dữ liệu phù hợp chưa? Nó có thực sự trả lời không?) Giống như cú pháp khai báo mảng trong PHP, nhưng tôi đề nghị những gì bạn thực sự muốn làm không phải là tìm con đường ngắn nhất từ ​​đầu vào đến đầu ra, mà là giải quyết nhiệm vụ được chỉ định:

  • Xác định rằng bạn có một enum
  • Trích xuất danh sách bên trong
  • Giải nén các giá trị danh sách

Đó gần như là những gì tùy chọn của bạn làm, nhưng tôi sẽ giới thiệu một số if và nhận xét xung quanh nó để rõ ràng và an toàn (ví dụ: nếu kết quả đầu tiên không khớp, hãy ném ngoại lệ hoặc đặt kết quả null).

Vẫn có một số vấn đề có thể xảy ra với dấu phẩy hoặc dấu ngoặc kép và bạn có thể nên giải nén dữ liệu sau đó hủy trích dẫn, nhưng ít nhất nó cũng coi dữ liệu là dữ liệu chứ không phải là mã.

Với preg_version, kết quả tồi tệ nhất của bạn có thể là $ result = null, với phiên bản eval, kết quả tồi tệ nhất là không xác định, nhưng ít nhất là một sự cố.


3

đánh giá một chuỗi dưới dạng mã, vấn đề với điều đó là nếu chuỗi bị "nhiễm bẩn" theo bất kỳ cách nào thì nó có thể gây ra các mối đe dọa bảo mật lớn. Thông thường, vấn đề là trong trường hợp đầu vào của người dùng được đánh giá trong chuỗi. được sử dụng để lấy thông tin / quyền truy cập vào máy chủ của bạn. Có thể khá khó khăn để đảm bảo thông tin đầu vào của người dùng được làm sạch đúng cách trước khi đưa nó đi đánh giá. Có những vấn đề khác ... một số trong số đó đang được tranh luận


3

PHP khuyên bạn nên viết mã của mình theo cách mà nó có thể được thực thi thông qua call_user_func thay vì thực hiện các hành động gợi ý rõ ràng.


2

Một lý do khác evallà không tốt, đó là nó không thể lưu vào bộ nhớ cache của mã bytecode PHP như eAccelertor hoặc ACP.


2

Đó là một chương trình tồi tạo ra eval () ác chứ không phải hàm. Đôi khi tôi sử dụng nó, vì tôi không thể sử dụng nó trong lập trình động trên nhiều trang web. Tôi không thể phân tích cú pháp PHP tại một trang web, vì tôi sẽ không nhận được những thứ tôi muốn. Tôi sẽ chỉ nhận được một kết quả! Tôi rất vui vì một hàm eval () tồn tại, vì nó giúp cuộc sống của tôi dễ dàng hơn nhiều. Người dùng nhập? Chỉ những lập trình viên tồi mới bị tin tặc móc túi. Tôi không lo lắng về điều đó.


2

Đó là một chương trình tồi tạo ra eval () ác chứ không phải hàm. Đôi khi tôi sử dụng nó, vì tôi không thể sử dụng nó trong lập trình động trên nhiều trang web. Tôi không thể phân tích cú pháp PHP tại một trang web, vì tôi sẽ không nhận được những thứ tôi muốn. Tôi sẽ chỉ nhận được một kết quả! Tôi rất vui vì một hàm eval () tồn tại, vì nó giúp cuộc sống của tôi dễ dàng hơn nhiều. Người dùng nhập? Chỉ những lập trình viên tồi mới bị tin tặc móc túi. Tôi không lo lắng về điều đó.

Tôi dự đoán bạn sẽ sớm gặp vấn đề nghiêm trọng ...

Thành thật mà nói, hoàn toàn không có việc sử dụng tốt cho một hàm cắt cổ như eval, trong một ngôn ngữ thông dịch chẳng hạn như PHP. Tôi chưa bao giờ thấy eval thực hiện các chức năng chương trình mà không thể được thực thi bằng các cách khác, an toàn hơn ...

Đánh giá là gốc rễ của mọi điều ác, tôi hết lòng đồng ý, với tất cả những người nghĩ rằng kiểm tra đầu vào của người dùng sẽ hữu ích. Hãy suy nghĩ kỹ, thông tin nhập của người dùng có thể ở nhiều dạng khác nhau và như chúng ta đã nói, tin tặc đang khai thác chức năng mà bạn không đủ quan tâm. Theo tôi, chỉ cần tránh đánh giá hoàn toàn.

Tôi đã thấy các ví dụ được tạo thủ công để lạm dụng chức năng eval vượt quá khả năng sáng tạo của tôi. Từ quan điểm bảo mật, hãy tránh bằng mọi giá, và tôi thậm chí sẽ đi xa đến mức yêu cầu nó ít nhất là một tùy chọn trong cấu hình PHP, chứ không phải là một 'cho sẵn'.


Lý do "cho dù bạn có cố gắng bảo mật mã của mình cẩn thận đến đâu liên quan đến tính năng X, thì các hacker thông minh luôn đi trước một bước ..." có thể được áp dụng cho bất kỳ kỹ thuật nào khác, không chỉ X == eval. Và do đó, đối với bất kỳ tính năng nào, X: X là gốc rễ của tất cả các eval ... er ... evil, vì vậy tốt hơn nên từ bỏ lập trình hoàn toàn (do đó, kéo thảm từ dưới tay những hacker ngớ ngẩn đó, cuối cùng vẫn vượt xa chúng).
Sz.

"hoàn toàn không được sử dụng tốt cho một hàm cắt cổ như eval" -> bất kỳ ai có thể sử dụng các từ như 'hoàn toàn', hoặc là người mới lập trình hoặc là một lập trình viên tồi.
100

2

Đây là một giải pháp để chạy mã PHP được lấy từ cơ sở dữ liệu mà không sử dụng eval. Cho phép tất cả các chức năng trong phạm vi và các ngoại lệ:

$rowId=1;  //database row id
$code="echo 'hello'; echo '\nThis is a test\n'; echo date(\"Y-m-d\");"; //php code pulled from database

$func="func{$rowId}";

file_put_contents('/tmp/tempFunction.php',"<?php\nfunction $func() {\n global \$rowId;\n$code\n}\n".chr(63).">");

include '/tmp/tempFunction.php';
call_user_func($func);
unlink ('/tmp/tempFunction.php');

Về cơ bản, nó tạo ra một hàm duy nhất với mã bao gồm trong một tệp văn bản, bao gồm tệp, gọi hàm, sau đó xóa tệp khi hoàn tất. Tôi đang sử dụng điều này để thực hiện nhập / đồng bộ hóa cơ sở dữ liệu hàng ngày trong đó mỗi bước yêu cầu mã duy nhất để xử lý để xử lý. Điều này đã giải quyết tất cả các vấn đề tôi đang phải đối mặt.


Điều này giống như một phản hồi cho một câu trả lời; xin vui lòng đăng nó như vậy khi bạn có thể.
rfornal

1

Tôi đã từng sử dụng eval () rất nhiều, nhưng tôi thấy hầu hết các trường hợp bạn không cần phải sử dụng eval () để làm thủ thuật. Vâng, bạn có call_user_func () và call_user_func_array () trong PHP. Nó đủ tốt để gọi bất kỳ phương thức nào một cách tĩnh và động.

Để thực hiện một cuộc gọi tĩnh, hãy xây dựng lệnh gọi lại của bạn dưới dạng mảng ('class_name', 'method_name') hoặc thậm chí là chuỗi đơn giản như 'class_name :: method_name'. Để thực hiện một cuộc gọi động, hãy sử dụng lệnh gọi lại kiểu mảng ($ object, 'method').

Cách sử dụng hợp lý duy nhất cho eval () là viết một trình biên dịch tùy chỉnh. Tôi đã tạo một cái, nhưng eval vẫn là ác, vì nó rất khó gỡ lỗi. Điều tồi tệ nhất là lỗi nghiêm trọng trong mã được đánh giá làm hỏng mã đã gọi nó. Tôi đã sử dụng tiện ích mở rộng Parsekit PECL để kiểm tra cú pháp ít nhất, nhưng vẫn không vui - hãy thử tham khảo các lỗi không xác định và toàn bộ ứng dụng.


0

Ngoài các mối quan tâm về bảo mật, eval () không thể được biên dịch, tối ưu hóa hoặc opcode được lưu vào bộ nhớ cache, do đó, nó sẽ luôn chậm hơn - chậm hơn - so với mã php bình thường. Do đó, việc sử dụng eval là không hiệu quả, mặc dù điều đó không khiến nó trở nên xấu xa. ( gotolà xấu xa, evalchỉ là tập tục xấu / mùi mã / xấu xí)


evalnhận được đánh giá ác thấp hơn goto? Có phải là ngày đối diện?
JLRishe

Chỉ là tôi có ác cảm với các nhà phát triển php vì đã thực sự triển khai gototrong 5.3.
Aron Cederholm

1
Không, đến goto-fobians: có những công cụ, và có những người thợ thủ công, những người sử dụng chúng (hoặc không). Đó không bao giờ là những công cụ khiến một người chuyên nghiệp trông giống như một tên ngốc, khi mắc lỗi, mà chính là việc không có khả năng sử dụng những công cụ thích hợp (đúng cách). Nhưng nó luôn là những công cụ đáng trách ...
Sz.

0

Hầu hết mọi người sẽ chỉ ra một thực tế là có thể nguy hiểm khi bạn xử lý thông tin đầu vào của người dùng (có thể xử lý được).

Đối với tôi, phần tệ nhất là nó làm giảm khả năng bảo trì mã của bạn:

  • Khó gỡ lỗi
  • Khó cập nhật
  • Giới hạn việc sử dụng các công cụ và trình trợ giúp (như IDE)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.