2016-11-30 1 views
0

질문은 다소 간단합니다 (어쩌면 조금 바보 스럽습니다). 그러나 예제를 드리겠습니다.
내가 작업하고있는 프로젝트에서 필자는 나를위한 기본적인 SQL 작업을 수행 할 몇 가지 함수 (클래스 메서드)를 만들었습니다. 필자가해야 할 일은 테이블 이름, 열 및 값과 같은 정보를 인수로 제공하고 나머지는 수행하는 것입니다. 말했다 PHP PDO에서 산술 연산을 수행하려면 어떻게해야합니까?

public function update_order($order_id, $order_value) {  
    $example_sth = $pdo->prepare("UPDATE example SET example_order = :order_value WHERE example_id = :order_id"); 
    $example_sth->bindParam(":order_id", $order_id); 
    $example_sth->bindParam(":order_value", $order_value); 
    $example_sth->execute(); 

    $data = $example_sth->fetch(); 
    return $data; 
} 

는, 지금의 내가 이런 쿼리를 수행한다고 가정하자 :

기능 구조는 기본적으로이 같은 것입니다

UPDATE example SET example_order = example_order + 1; 

나는 SQL 작업을 수행 할 수 PDO를 사용하기 때문에 , 어쨌든 PDO의 bindParam() 함수 안에 "example_order + 1"부분을 전달할 수 있습니까? 아니면 유일한 해결책은 PDO 변수를 완전히 제거하고 산술 연산을 직접 쿼리에 작성하는 것입니까?

미리 도움을 청하십시오.

UPDATE

간단하게하기 위해, 내가 질문에 포함되지 않은 것을 추가 정보가 있습니다. 제기되는 혼동이 있기 때문에, 나는이 모든 것을 가지고 나의 의도를 이해하고자하는 사람들을 위해 여기에 이것을 포함시킬 것이다.

내가 작업하고있는 프로젝트는 RPG와 같은 사이트로, 사용자가 속성 포인트, 특수 효과가있는 항목 등이 있습니다.
이 사용자 속성 및 항목 효과는 모두 관리자가 생성하거나 조작합니다.

이러한 항목 효과는 사용자가 더 많은 속성 포인트를 제공 할 수 있기 때문에 (전체 프로필 작성 또는 삭제와 같은 더 복잡한 작업을 수행 할 수도 있음), 유일한 해결책은 이 효과를 SQL 작업으로 전환하는 것이 었습니다.
보안 위반을 피하기 위해 관리자가 직접 이러한 SQL 작업을 저장하는 관리자 사용자를 허용하지 않으므로 다음과 같이 간단한 JSON 명령을 저장하는 것이 좋습니다.

{"update":[ 
    {"columns":"order_id, order_value", 
    "values":"16281738, 16"} 
]} 

admin 사용자는 간단한 컨트롤 패널을 통해 항목 효과에서 수행 할 항목을 선택하면이를 기반으로 JSON이 자동으로 생성됩니다.

효과가 일반 사용자에 의해 실행될 때이 JSON 명령은 모두 SQL 조작을 담당하는 클래스 메소드 (위에서 언급 한 것)로 전달되어야합니다.

이제 질문을 받았습니다 : 왜 산술 연산을 저장해야합니까?

대답은 :

이 항목의 효과 중 하나는 사용자에게 특별히 만든 경우, 나는 단순히 아이템의 효과를 작성하기 전에 자신에 의해 계산을 수행 할 수 있습니다 알고, 그래서 JSON 명령은 이미 최종 포함 할 것 결과 (예 : ""column ":"life_ponts ","value ","77 "").
그러나 이러한 작업/항목 효과는 사용자에게만 전달되는 것이 아니므로 주관적이어야합니다 (즉, 현재 실행중인 사용자를 기반으로하는 작업).
이 때문에 유일한 결과는 최종 결과 (이 상황에서는 불가능 함)를 저장하지 않고 해당 속성 포인트에서 수행해야하는 산술 연산을 저장하는 것입니다.
"" "column": "life_points", "value": "life_points +1" "을 저장하면 현재 사용자가 명령을 실행하는 life_points를 얻는 중입니다. 그것을 1 씩 늘리십시오.

나는 그것이 혼란스럽고 어쩌면 틀린 것처럼 들리므로 나는 더 나은 제안을하기에 전적으로 열려 있습니다. 오해 때문에 유감스럽게도, 여러분들이 나를 도울 수 있기를 바랍니다.
감사합니다!

+5

왜 바인딩해야합니까? params 바인딩의 요점은 SQL 삽입, 즉 사용자가 쿼리에 SQL 코드를 삽입하는 것을 방지하는 것입니다. 값을 하나씩 만 늘리려는 경우 쿼리를 실행할 수 있습니다. 사용자 입력이 없습니다. –

+0

예, 알겠습니다, @ AurelBílý. 그러나 내가 만든 클래스 메서드는 해당 테이블과 관련된 모든 UPDATE 작업의 표준으로 작동해야하므로 모든 종류의 정보 (사용자 입력 또는 질문에서 언급 한 것과 같은 간단한 산술 연산 포함)를 받아 들여야합니다. 한 가지 또는 다른 작업을 수행 할 때 매우 다양하므로 적합하지 않은 쿼리로 인해 메서드를 변경할 필요가 없습니다. –

+0

사용자가 산술 연산을 전송하는 방법은 무엇입니까? 입력은 어떻게 생겼습니까? 그러면이 스크립트는 항상 동일한 필드를 업데이트합니까, 아니면 업데이트되는 필드는 사용자 입력에 따라 달라 집니까? – Dragos

답변

0

바인딩은 필드 이름이 아닌 으로 설계되었습니다. 찾고자하는 것은 변경할 수있는 필드의 흰색 목록입니다. 대신 이들의 집합으로,

  1. 당신은 열 당 동작을 설정 :

    여기
    { 
        "update": [ 
         { 
          "column": "order_id", 
          "type": "relative|absolute", 
          "value": 16281738 
         } 
        ] 
    } 
    

    것은 무슨 일이야있다 : 당신이 더이을하려면

    ,이 같은 일을하는 것이 좋습니다 . 당신 화이트리스트을 사용해야합니다!

  2. 새 필드가 추가되었습니다 - "유형". 상대절대의 두 값만 취할 수 있으며 어떤 유형의 작업을 수행할지 지정합니다. 다른 값이있는 경우 위험하므로 폐기하거나 예외를 throw해야합니다.
  3. 값은 정수/부동 소수입니다. json_decode 때 이것을 int/float로 변환하거나 if (is_numeric())을 확인해야합니다. 주입 위험없이 int/float를 SQL 쿼리로 안전하게 대체 할 수 있기 때문에 이것은 중요합니다. 그것을 지정하려면 유형 필드를 사용하여 -

마지막으로 당신은 때때로 복잡한 작업을 필요로했다. 그러나 다른 값이 필요하지 않은 경우에는 대신 부울 값 사용을 고려하십시오.

관련 문제