2016-10-19 2 views
0

Я пытаюсь внедрить систему подсчета кликов. Я использую следующий код в этой ссылке Click here to see code, но меняя его на современные стандарты. Первоначально я получал ошибки для строки msqli_real_escape_, но я считал, что разрешил (без ошибок). Теперь я вообще не получаю никаких ошибок, но запрос не отправляется в мою базу данных. Я использую ini_set('display_errors', 1); error_reporting(E_ALL); для проверки ошибок. Также у меня есть мои и session файлы ini и ini, которые я вызываю, поэтому сеанс и соединение не являются проблемами.Запрос не входит в базу данных

Кто-нибудь видит, что я делаю неправильно, или есть хороший способ проверить, что не работает?

//create current page constant 
$curPage = mysqli_real_escape_string($con,htmlspecialchars($_SERVER['PHP_SELF'])); 

//set number of clicks variable to 0 
$clicks = 0; 

//do not recount if page currently loaded 
if($_SESSION['page'] != $curPage) { 
    //set current page as session variable 
    $_SESSION['page'] = $curPage; 

    $click_sql = " 
    SELECT * 
    FROM click_count 
    WHERE page_url = ? 
    "; 
    if (!$click_stmt = $con->prepare($click_sql)) { 
     $click_stmt->bind_param("s", $curPage); 
     $click_stmt->execute(); 
     $num_rows = $click_stmt->fetchColumn(); 
     if (!$click_stmt->errno) { 
      // Handle error here 
     } 
     $stmt->bind_result($click_id, $page_url, $page_count); 
    } elseif ($num_rows == 0) { 
     //try to create new record and set count for new page to 1 
     //output error message if problem encountered 
      $click_insert_stmt = " 
      INSERT INTO click_count 
      (page_url, page_count) 
      VALUES(?, ?)"; 

     if(!$click_stmt = $con->prepare($click_insert_stmt)) { 
      $click_insert_stmt->execute(array('$curPage',1)); 
      echo "Could not create new click counter."; 
     } 
     else { 
      $clicks= 1; 
     } 
    } else { 
    //get number of clicks for page and add 1  fetch(PDO::FETCH_BOTH) 
     while($click_row = $click_insert_stmt->fetch(PDO::FETCH_BOTH)) { 
      $clicks = $row['page_count'] + 1; 
      //update click count in database; 
      //report error if not updated 

      $click_update_stmt = " 
      UPDATE click_count 
      SET page_count = ? 
      WHERE page_url = ? 
      "; 
      if(!$click_stmt = $con->prepare("$click_update_stmt")) { 
       $click_update_stmt->execute(array('$clicks', '$curPage')); 
       echo "Could not save new click count for this page."; 
     } 
     } 
    } 
} 

Edit: Новый обновленный код

// ********Page count************ 

//create current page constant 
$curPage = mysqli_real_escape_string($con,($_SERVER['PHP_SELF'])); 

//set number of clicks variable to 0 
$clicks = 0; 

//do not recount if page currently loaded 
if($_SESSION['page'] != $curPage) { 
    //set current page as session variable 
    $_SESSION['page'] = $curPage; 

    $click_sql = " 
    SELECT * 
    FROM click_count 
    WHERE page_url = ? 
    "; 
    if (!$click_stmt = $con->prepare($click_sql)) { 
     $click_stmt->bind_param("s", $_SERVER['PHP_SELF']); 
     $click_stmt->execute(); 
     $num_rows = $click_stmt->fetchColumn(); 
     if (!$click_stmt->errno) { 
      // Handle error here 
     } 
     $stmt->bind_result($click_id, $page_url, $page_count); 
    } elseif ($num_rows == 0) { 
     //try to create new record and set count for new page to 1 
     //output error message if problem encountered 
      $click_insert_stmt = " 
      INSERT INTO click_count 
      (page_url, page_count) 
      VALUES(?, ?)"; 

     if(!$click_stmt = $con->prepare($click_insert_stmt)) { 
      $click_insert_stmt->execute(array($curPage,1)); 
      echo "Could not create new click counter."; 
     } 
     else { 
      $clicks= 1; 
     } 
    } else { 
    //get number of clicks for page and add 1  fetch(PDO::FETCH_BOTH) 
     while($click_row = $click_insert_stmt->fetch(PDO::FETCH_BOTH)) { 
      $clicks = $row['page_count'] + 1; 
      //update click count in database; 
      //report error if not updated 

      $click_update_stmt = " 
      UPDATE click_count 
      SET page_count=page_count+1 
      WHERE page_url = ? 
      "; 
      if(!$click_stmt = $con->prepare("$click_update_stmt")) { 
       $click_update_stmt->execute(array($curPage)); 
       echo "Could not save new click count for this page."; 
     } 
     } 
    } 
} 
+0

Кроме того, это, '-> fetch (PDO :: FETCH_BOTH)) {'. Почему вы смешиваете 'MySQLi' и' PDO'? –

+0

Я только начал изучать PDO, поэтому я пытаюсь записать его в этом коде. Преобразование из старого mysql всегда меня смущает. – Paul

+0

PDO не так много отличается концептуально, есть только небольшие различия в именах методов. С первого взгляда сложно сказать PDO-код из 'mysqli'. – tadman

ответ

3

Похоже, что вы делаете много вещей, как это:

$click_update_stmt->execute(array('$clicks', '$curPage')); 

Я не уверен, где вы взяли этот привычка цитирования переменных как строки, но вам нужно отказаться от нее. '$x' и $x - это две совершенно разные вещи. В первом случае это буквально'$x', а во втором случае это то, что представляет собой переменная $x.

Fix это так:

$click_update_stmt->execute(array($clicks, $curPage)); 

Кроме того, поскольку вы используете подготовленные заявления, которые, кстати, это здорово, вы не должны и не должен вручную избежать ваших ценностей. Применение их к заполнителям с bind_param - безопасный способ сделать это. Выполнение любых других экранов искажает данные.

Просто связываться непосредственно к источнику:

$click_stmt->bind_param("s", $_SERVER['PHP_SELF']); 

ли произвольно не запускать вещи, как htmlspecialchars на вход из паранойи или потому, что вы делаете грузопассажирские культовое программирование и вы видели это сделано в учебнике YouTube где-то. Эта функция предназначена для использования только для значений , а не для их хранения. Данные в вашей базе данных должны быть как можно более сырыми.

Существует много проблем с этим кодом, и один из них, который меня смутил, - это то, что есть код. Помните SELECT *, а затем привязка результатов к произвольным переменным - проблема, ваша схема может измениться, а затем ваш код не синхронизирован. Когда это возможно, выбирайте строки как ассоциативный массив, если вы это сделаете, тогда все, о чем вам нужно беспокоиться, переименовано в удаленные столбцы.

Самая большая проблема заключается в том, что это зависит от условий гонки, поскольку оно не использует атомный приращение . При написании счетчиков, всегда делать свои обновления, как операции, которые один оператор:

UPDATE click_count SET page_count=page_count+1 WHERE page_url=? 

Ваш подход чтение счетов, увеличивая его, а затем записывая его обратно в базу данных означает, что вы приглашаете проблемы если другая операция выполняется одновременно, что-то очень вероятно в коде кликов.

+0

Спасибо, это помогло мне многому научиться. Хотя я смущен, когда вы говорите, что мне не нужно избегать моих ценностей. Вы имеете в виду, когда я выполняю выполнение? Я добавил свой новый код на основе ваших предложений. Он по-прежнему не вставляет в мой db. – Paul

+0

Я имею в виду «предварительно убежать» от них или вручную избежать их. Помните, что 'bind_param' делает это за вас. Если вы сделаете это, вы получите в своей базе данных такие вещи, как «It \\\ me!». Общее правило: ** escape или bind **, но не оба. – tadman

+0

Можете ли вы привести мне пример того, что я делаю, чтобы лучше понять? Вы видите что-то еще в моем новом коде, что я делаю неправильно? – Paul

Смежные вопросы