2013-06-04 2 views
1

개발과 관련하여 저는 PHP와 MySQL을 처음 접했습니다. 나는 모든 것을 올바르게하고 있는지 확인하기 위해 조언을 듣고 싶다. 나는 올바른 방법으로 변환 된 것으로 생각되는 한 페이지와 변환해야하는 한 페이지를 가지고 있습니다.SQL을 PDO로 변환하여 SQL 인젝션을 방지하십시오.

여기에 제가 설정 한 것이 맞습니까? 여기

그리고

<?php $title = 'SEARCH'; $page = '';include 'includes/header.php';?> 

<body> 

<?php include 'includes/nav.php'; ?> 

<?php 
$q = $_GET['q']; 

// CONNECT TO THE DATABASE 
$DB_NAME = 'code_storage'; 
$DB_HOST = 'localhost'; 
$DB_USER = 'user'; 
$DB_PASS = 'pass'; 

try { 
    $dbcon = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME", $DB_USER, $DB_PASS); 
    //echo 'Connected to database'; 

    $sql = <<<SQL 
    SELECT * 
    FROM snippets 
    WHERE CODE_NAME LIKE '%$q%' OR 
    CODE_DESC LIKE '%$q%' OR 
    CODE_TAGS LIKE '%$q%' OR 
    CODE_USAGE LIKE '%$q%' 
SQL; 
    echo '<div class="row">'; 
    echo '<div class="panel">'; 
     printf("Your search for <b>$q</b> returned %d records.\n", $dbcon->query($sql)->rowCount()); 
    echo '</div>'; 
    echo '</div>'; 

    foreach ($dbcon->query($sql) as $row) { 
     //print $row['CODE_NAME'] . '<br/>' . "\n"; 
     echo ' <div class="row">' . "\n"; 
     echo '  <div class="large-12 columns">' . "\n"; 
     echo '    <b><a href="results.php?id=' . $row['_ID'] . '">' . $row['CODE_NAME'] . '</a></b><br/><br/>' . "\n"; 
     echo '  </div>' . "\n"; 
     echo ' </div>' . '<br/><br/>' . "\n"; 
    } 


    $dbcon = null; 
} 
catch(PDOException $e) 
{ 
    echo $e->getMessage(); 
} 
?> 
<?php include 'includes/footer.php';?> 
난 아직도이가 한 번 난 정말 여기입니다

<?php 

// CONNECT TO THE DATABASE 
$DB_NAME = 'code_storage'; 
$DB_HOST = 'localhost'; 
$DB_USER = 'user'; 
$DB_PASS = 'pass'; 


$mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); 

if (mysqli_connect_errno()) { 
    printf("Connect failed: %s\n", mysqli_connect_error()); 
    exit(); 
} 

// Fix for the ' and " 

$_POST['name'] = $mysqli->real_escape_string($_POST['name']); 
$_POST['desc'] = $mysqli->real_escape_string($_POST['desc']); 
$_POST['usage'] = $mysqli->real_escape_string($_POST['usage']); 
$_POST['code'] = $mysqli->real_escape_string($_POST['code']); 
$_POST['tags'] = $mysqli->real_escape_string($_POST['tags']); 

$sql = <<<SQL 
    INSERT 
    INTO snippets 
    (CODE_NAME,CODE_DESC,CODE_USAGE,CODE_SYNTAX,CODE_TAGS) 
    VALUES 
    ('$_POST[name]', '$_POST[desc]', '$_POST[usage]', '$_POST[code]', '$_POST[tags]'); 
SQL; 

if(!$result = $mysqli->query($sql)){ 
    echo '<br/><br/><br/><br/>' . "\n"; 
    echo '<div class="row">' . "\n"; 
    echo ' <div class="large-12 columns">' . "\n"; 
    echo '  <div data-alert class="alert-box alert">' . "\n"; 
    echo '   There was an error' . "\n"; 
    echo '   <a href="../site/upload.php" class="close">&times;</a>' . "\n"; 
    echo '  </div>' . "\n"; 
    echo ' </div>' . "\n"; 
    echo '</div>' . "\n"; 
    echo '<br/><br/><br/><br/>' . "\n"; 
    echo '<div class="row">' . "\n"; 
    echo ' <div class="large-12 columns">' . "\n"; 
    die('There was an error with the code [' . $mysqli->error . ']'); 
    echo ' </div>' . "\n"; 
    echo '</div>' . "\n"; 

} 
    echo '<br/><br/><br/><br/>' . "\n"; 
    echo '<div class="row">' . "\n"; 
    echo ' <div class="large-12 columns">' . "\n"; 
    echo '  <div data-alert class="alert-box success">' . "\n"; 
    echo '   Code Successfully Added' . "\n"; 
    echo '   <a href="../site/" class="close">&times;</a>' . "\n"; 
    echo '  </div>' . "\n"; 
    echo ' </div>' . "\n"; 
    echo '</div>' . "\n"; 
    echo '<br/><br/><br/><br/>' . "\n"; 
*/ 

?> 

* 편집으로 * 을 도움을 사용할 수 있습니다 변환해야 하나입니다 나는 지금까지 가지고있는 것이지만 어떤 기록을 되 돌리고있는 것 같지 않은 이유는 무엇입니까?

$q = $_GET['q']; 

$DB_NAME = 'code_storage'; 
$DB_HOST = 'localhost'; 
$DB_USER = 'user'; 
$DB_PASS = 'pass'; 


$dsn = "mysql:host=$DB_HOST;dbname=$DB_NAME"; 
$db = new PDO($dsn, $DB_USER, $DB_PASS); 

$query = "SELECT * FROM `SNIPPETS` WHERE `CODE_NAME` LIKE :name OR `CODE_DESC` LIKE :name OR `CODE_TAGS` LIKE :name OR `CODE_USAGE` LIKE :name"; 
$prep = $db->prepare($query); 
$prep->execute(array(":name" => "%" . $q . "%")); 

echo '<div class="row">'; 
    echo '<div class="panel">'; 
     printf("Your search for <b>$q</b> returned %d records.\n", $prep->rowCount()); 
    echo '</div>'; 
echo '</div>'; 

while ($row = $prep->fetch()) { 
    echo ' <div class="row">' . "\n"; 
    echo '  <div class="large-12 columns">' . "\n"; 

    echo    $row['CODE_NAME'] . '<br/><br/>' . "\n"; 
    echo    $row['CODE_DESC'] . '<br/><br/>' . "\n"; 
    echo    $row['CODE_USAGE']. '<br/><br/>' . "\n"; 
    echo '  </div>' . "\n"; 
    echo ' </div>' . '<br/><br/>' . "\n"; 


} 

$db = null; 

내가 불행하게도이 오류

Connection failed: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens 
+0

주입 방지에 대한 추가 정보 : http://stackoverflow.com/questions/60174/how-to-prevent-sql-injection-in-php?lq=1 – BLaZuRE

+4

mysqli는 바인딩 된 매개 변수도 제공합니다. PDO로 전환 할 필요가 없습니다 (비록 인터페이스는 좋지만). 첫 번째 스 니펫 (btw)은 딱 맞습니다. 그것은 여전히 ​​입력을 직접 보간하고, 도망 치거나, 준비된 진술을 표시합니다. – mario

+0

우리 [PDO 튜토리얼 for MySQL 개발자] (http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers)에서 유용한 것을 발견 할 수 있습니다. – TML

답변

1

를 얻고 있다는 것을 발견, PDO의 일부 버전은 동일한 쿼리에서 명명 된 매개 변수를 여러 번 사용하는 방법을 모르겠어요. 이 버그는 최신 버전에서는 수정되었지만 이전 버전의 PDO를 사용하면 문제가 발생할 수 있습니다.

$query = "SELECT * FROM `SNIPPETS` WHERE `CODE_NAME` LIKE :name1 
    OR `CODE_DESC` LIKE :name2 
    OR `CODE_TAGS` LIKE :name3 
    OR `CODE_USAGE` LIKE :name4"; 
$prep = $db->prepare($query); 
$qpattern = "%" . $q . "%"; 
$prep->execute(array(":name1" => $qpattern, ":name2" => $qpattern, ":name3" => $qpattern, ":name4" => $qpattern)); 

또는 다른 위치 매개 변수 대신 명명 된 매개 변수 사용 :

$query = "SELECT * FROM `SNIPPETS` WHERE `CODE_NAME` LIKE ? 
    OR `CODE_DESC` LIKE ? 
    OR `CODE_TAGS` LIKE ? 
    OR `CODE_USAGE` LIKE ?"; 
$prep = $db->prepare($query); 
$qpattern = "%" . $q . "%"; 
$prep->execute(array_fill(0, 4, $qpattern)); 

PS : 준비된 문을 사용하는 방법에 대한 질문과 관련되지하지만 '%pattern%'의 사용을

한 가지 해결 방법은 이것이다 전체 텍스트 검색은 thousands of times slower than using any fulltext index solution입니다.


또 다른 좋은 습관에 오류가 확인하는 것입니다 PDO 모든 호출 후) (:: 준비() 또는 PDOStatement는 :: 실행합니다. 어느 예외 모드를 사용하거나 다른 false의 반환 값을 확인하십시오

if (($prep = $db->prepare(...)) === false) { 
    // check $db->errorInfo() for details 
} 
if ($prep->execute(...) === false) { 
    // check $prep->errorInfo() for details 
} 

오류를 확인하는 것도 기존의 MySQL의 API에 대한 모범 사례 및 mysqli API입니다.

+0

정말 고맙습니다. 준비된 진술에 대해 머리 글자를 쓰지 만 다시 감사드립니다. – ondrovic

+1

위대한 예제에 대해 빌 다시 한 번 감사드립니다. 이제 준비된 명령문과 PDO를 사용하도록 모든 코드를 변환했습니다.나는 아직 전체 텍스트 색인 솔루션을 살펴 보았지만 이번 주말에 계획을 세웠다. – ondrovic

관련 문제