2011-08-29 12 views
7

Trong ứng dụng hiện tại của chúng tôi Tôi có một báo cáo có chứa một cái gì đó như:Làm thế nào tôi có thể lưu trữ một staement có điều kiện PHP trong cơ sở dữ liệu để sử dụng sau này?

if($foo == 3 || $bar > 3) { 
    $e = someFunction(); 
}; 

nhưng đối với một khách hàng khác nhau mà cùng một biểu hiện có thể là:

if($foo == 3 || $bar == 5 && $foobar != 9) { 
    $e = someFunction(); 
}; 

Có một cách thẳng thắn để lưu trữ các hai biểu thức khác nhau, chỉ cần

$foo == 3 || $bar > 3 OR $foo == 3 || $bar == 5 

bit trong cơ sở dữ liệu (MySQL) vì vậy tôi không phải mã cứng tất cả các quy tắc này của khách hàng hoặc duy trì các phiên bản ứng dụng khách của cùng một báo cáo. Tôi đang cố gắng tìm ra nếu tôi có thể thiết lập một biến o thay thế các điều kiện. Một cái gì đó như:

$conditions = $row_rsConditions['condition_row'] //Get $foo == 3 || $bar > 3 from the DB and store it as $conditions 
if($conditions) { 
    $e = someFunction(); 
}; 

Có thể có> 100 khách hàng khác nhau và mỗi khách hàng có thể/sẽ có một bộ biểu thức khác. Tôi không chắc chắn về cách tốt nhất để làm điều này.

CẬP NHẬT:

Tôi nghĩ rằng tôi hiểu được vấn đề sử dụng eval PHP() chức năng. Nhưng vì số lượng các kết hợp có thể tôi đang hướng tới việc sử dụng DB để lưu trữ các điều kiện (không chắc chắn về việc sử dụng eval())

Nó có tạo sự khác biệt (an toàn hơn) nếu không có giao diện người dùng ghi vào trường điều kiện/bảng? Nó có thể là một cái gì đó chúng tôi quản lý về phía chúng tôi một mình.

+4

Làm thế nào để lưu mã vào cơ sở dữ liệu và sau đó tải và thực thi bằng cách sử dụng 'eval' ? Thoug có thể có vấn đề an ninh khi ai đó tiêm cơ sở dữ liệu và làm cho bạn đánh giá mã của mình. – Nobody

+0

Sau đó, câu hỏi đặt ra là, trong hoàn cảnh nào, các toán tử bên trong điều kiện đó có thể thay đổi? – Deele

+5

Tôi nghĩ rằng thiết kế rất xấu để lưu trữ logic trong cơ sở dữ liệu, cơ sở dữ liệu chỉ nên được sử dụng cho dữ liệu – Fivell

Trả lời

3

tôi sẽ rất cẩn thận về việc lưu trữ logic trong cơ sở dữ liệu.

  1. mã của bạn không còn ở cùng một nơi.
  2. logic trong cơ sở dữ liệu không được kiểm soát nguồn
  3. nếu bạn thay đổi mã và ngắt tất cả logic cụ thể của khách hàng đó, bạn phải quay lại cơ sở dữ liệu và chỉnh sửa nó cho mọi khách hàng.
  4. người khác có thể có quyền truy cập vào cơ sở dữ liệu và có thể thay đổi mã thành nội dung độc hại.

điều này có thể không phải là giải pháp tốt nhất nhưng tôi sẽ khuyên bạn nên tạo một lớp cơ sở trừu tượng, sau đó kế thừa từ đó, một lớp học cụ thể cho từng khách hàng.

Bất kỳ chức năng nào được tùy chỉnh đều có thể được thêm làm phương thức cho lớp cơ sở và được ghi đè để triển khai cụ thể cho ứng dụng khách.

sử dụng câu lệnh chuyển đổi để khởi tạo lớp dựa trên id hoặc tên ứng dụng khách (điều gì đó không thay đổi) mà bạn đã lưu trữ trong cơ sở dữ liệu.

switch ($client_name) { 

case "abc ltd": 
    $customlogic = new CustomLogicAbc(); 
    break; 

case "zyx ltd": 
    $customlogic = new CustomLogicXyz(); 
    break; 

default: 
    $customlogic = new CustomLogicDefault(); 
    break; 

} 

if ($customlogic->doSomething($parm1, $parm2)) { 
    // custom logic has been applied 
} 
+0

Tôi nghĩ vấn đề tương đối đơn giản, có nghĩa là anh ta chỉ kiểm tra hai giá trị đó. Nhưng anh ta có rất nhiều điều kiện khác nhau đối với họ rằng tất cả sẽ phải được mã hóa. Thay vào đó parametrizing này sẽ chỉ yêu cầu một thực hiện và lấy các điều kiện như anh ta muốn nó. – Nobody

+0

Vì vậy, nếu có hơn 100 khách hàng, tùy chọn này vẫn khả thi? Tôi sẽ đồng ý với số 1 và # 2 của bạn. # 3 là để chúng tôi duy trì đúng cách và # 4 - nếu họ có thể thay đổi điều đó thì họ có thể gây ra nhiều thiệt hại hơn, đúng không? – Jason

+0

nó thực sự phụ thuộc vào bao nhiêu logic tùy chỉnh bạn có và nó phức tạp như thế nào. nếu bạn chỉ có 1 câu lệnh được hiển thị trong ví dụ của bạn, thì tốt hơn bạn nên lưu trữ các thông số $ foo và $ bar trong cơ sở dữ liệu đối với từng bản ghi ứng dụng khách thay vì sau đó là logic thực tế. Nếu bạn có nhiều câu lệnh tùy chỉnh và chúng phức tạp, thì tôi sẽ làm như tôi đã làm ở trên, vì cơ hội là logic sẽ chỉ phức tạp hơn khi bạn đi, và bạn sẽ thêm nhiều công cụ tùy chỉnh hơn – bumperbox

2

Để xây dựng trên nhận xét của tôi:

đang cuối cùng của bạn là gần như những gì tôi có nghĩa là:

$conditions = $row_rsConditions['condition_row']; //Get "$foo == 3 || $bar > 3" 
if(eval("return (" . $conditions . ");")) { 
    $e = someFunction(); 
} 

Tuy nhiên tôi sẽ cảnh báo bạn một lần nữa để nhớ những nguy cơ để làm điều này. Khi bạn sử dụng mã từ cơ sở dữ liệu, có khả năng là có lỗi. Ít nhất một số kiểm tra an ninh nên được thực hiện trên dữ liệu để tránh lạm dụng.

Một tùy chọn khác phức tạp hơn một chút nhưng không dễ bị lạm dụng sẽ là mã hóa các điều kiện. Có vẻ như bạn chỉ so sánh 2 biến với một giá trị mà mỗi bạn có thể lưu cho mỗi biến như sau:

0 != 
1 == 
2 >= 
3 <= 
4 > 
5 < 

Để lưu mối quan hệ và tiết kiệm thêm giá trị cần so sánh. Bằng cách đó, không có mã thực thi trực tiếp nào được lưu trong cơ sở dữ liệu.

+0

Vô cùng không an toàn! – Gustav

+0

@Gustav - Có an toàn không vì tôi sẽ mở một địa điểm để cho phép tiêm mã hoặc có điều gì đó hơn thế không? – Jason

+0

@ Jason Phần PHP-injection là tồi tệ nhất. – Gustav

0

không ai có thể nói cho bạn biết làm thế nào để giải quyết nó bởi vì không ai biết yêu cầu chức năng và logic cụ thể của ứng dụng của bạn ... Nhưng nếu thời gian thực hiện là rất quan trọng cho bạn, bạn có thể ofcourse cố gắng sử dụng evaluationg các biểu thức từ cơ sở dữ liệu, nhưng hãy cẩn thận và sử dụng sanitazing của tất cả dữ liệu từ cơ sở dữ liệu ... Có một ví dụ how to make php expressions and execute from database? - bạn chỉ cần thêm logic hơn vì bạn có thể có điều kiện nhân

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