2016-05-04 3 views
3

Я следую this tutorial, чтобы попытаться создать скрипт проверки ключа PHP Form. По какой-то причине мой конструктор не создает значение для моей переменной $old_formKey.Что-то не так с моей PHP-формой Класс ключа

В учебнике упоминается, что синглтоны более безопасны, но он не входит в реализацию. Я знаю основные принципы ООП с Java, но я мало знаю о Принципах ООП PHP. Я просто пытался взломать его, сделав переменные класса статическими - и я думаю, что это моя проблема. Однако, когда мой конструктор вызывается, он должен дать $old_formKey значение $_POST[form_key] «если Исеть()»

Я не в состоянии получить конструктор, чтобы поместить значение старого formKey в желаемом переменном пространстве.

Так вот, где у меня проблемы.

<?php 
class formKey 
{ 
    private static $formKey; 

    private static $old_formKey; 

    public function validate() 
    { 
     echo $_POST['form_key']; 
     //We use the old formKey and not the new generated version 
     if($_POST['form_key'] == $old_formKey) { 
      //The key is valid, return true. 
      return true; 
     } 
     else { 
      //The key is invalid, return false. 
      return false; 
     } 
    } 
} 
?> 

My formKey validation script выглядит примерно так.

<?php 
if ($_SERVER["REQUEST_METHOD"] == "POST") { 
    //Validate the form key 
    if(!isset($_POST['form_key']) || !$formKey->validate()) { 
     //Form key is invalid, show an error 
     $error_msg = 'Security Error.'; 
     $die = "die"; 
    } 
    else { 
     /*continue validation*/ 
    } 
} 
?> 

Скрипт возвращает сообщение об ошибке, а затем выводит его, потому что $old_formKey никогда не дается значение внутри метода validate().

По какой-то причине я не могу изменить переменную класса из метода validate(). Извините, если это было рассмотрено ранее. Я честно посмотрел и не мог найти его!

function __construct() 
{ 
    //We need the previous key so we store it 
    if(isset($_SESSION['form_key'])) 
    { 
     self::$old_formKey = $_SESSION['form_key']; 
    } 
} 

Извините, что забыл включить мой конструктор. Это было добавлено выше.

+8

** 12 июн 2009 г. ** опасность любого учебного пособия в течение 7 лет должна быть опасно устаревшей –

+0

Для реализации одноэлементной переменной вы должны использовать 'self', поскольку она статична. Вы также должны назначить его 'self :: $ old_formKey = 'whatever';' То же самое с '$ formKey'. При этом, даже если у вас есть это, вы не присвоили '$ old_formKey' какое-либо значение. – Rasclatt

+0

Также вы говорите * «когда мой конструктор вызывается ...» *, вы имеете в виду '__construct()'? Если это так, у вас его нет, по крайней мере, из приведенного вами примера. – Rasclatt

ответ

0

Как я уже писал в качестве комментария, учебник, упомянутый вами как Dagon написал, устарел, второй его полностью фиктивный.

Это не имеет ничего общего с проверки формы, в центре внимания на этой теме идентификации формы.

Вы генерируете уникальный идентификационный ключ, который генерируется сервером (в данном случае PHP), чтобы отслеживать состояние форм. Если уникальный ключ изменяется, в котором он будет отличаться от ключа , хранящегося на сервере, форма может быть отклонена там, где она не может быть идентифицирована (это вовсе не означает, что форма не действительна) ,

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

  1. Создать уникальный ключ и хранить его в пользователях (или посетители, зависят от терминологии здесь, я буду описывать их как users теперь) SESSION
  2. Выхода ключ в форме
  3. Определить форму на покориться и сравнить (неопознанных) ключ против ключа (идентифицированного) (ов) хранящегося в SESSION

    4.1. Подтвердить форму при выполнении лимита

    4.2. Отклонение формы, если не в состоянии идентифицировать

Начиная с генерацией, например, расположение класса довольно просто, не нужно быть singleton и не должно содержать ничего статический.

Основание класса может быть разделена на три секции, создания, хранения и идентификации.

class FormIdentifier { 

    const CONTAINER_KEYSPACE = 'form_keys'; 

    /** 
    * Generate a key 
    * @return string 
    */ 
    public function generateKey() { 
    // you can use any complicated mumbo-jumbo to generate a key instead 
    $key = uniqid(); 
    // store it 
    $this->storeKey($key); 
    // return for use, e.g. in a form 
    return $key; 
    } 

    /** 
    * Store a key into users session 
    */ 
    protected function storeKey($key) { 
    session_start(); 
     $_SESSION[self::CONTAINER_KEYSPACE][] = $key; 
    session_write_close(); 
    } 

    /** 
    * Identifies a key against the keys in the users stored session. 
    * @return true if identified, false otherwise 
    */ 
    public function identifyKey($key) { 
    session_start(); 
     if(($found = search_array($key, $_SESSION[self::CONTAINER_KEYSPACE])) !== false) { 
     unset($_SESSION[self::CONTAINER_KEYSPACE][$found]); 
     session_write_close(); 
     return true; 
     } 

    session_write_close(); 
    return false; 
    } 
} 

Чтобы сгенерировать ключ, мы не будем смешивать вывод HTML с классами и методами. FormIdentifier s цель только создание, хранение и идентификация ключи формы, ничего больше. Так пример для использования в виде

<form> 
    <input type="hidden" name="form_key" value="<?php (new FormIdentifier)->generateKey() ?>" /> 
</form> 

Вы также можете хранить возвращенное ключ где-то и использовать его по-другому, независимо Suítes ваши потребности.

<?php $key = (new FormIdentifier)->generateKey(); ?> 
<input type="hidden" name="form_key" value="<?= $key ?>" /> 

Чтобы определить (и в конечном итоге утвердить) форму, вы можете указать формы, размещенные ключ и сравнить его с ключом (ами), хранящегося в сессии пользователей. Используемая здесь структура скорее всего покажет пользователю некоторое уведомление о несоответствии ключа. Это полностью зависит от того, как вы хотите реализовать этот шаг, вы можете обернуть его в функцию или даже объединить его с классом FormIdentifier.

/** 
* Simple if/else, a POST was made so act on `form_key`s presence only 
*/ 
if($_POST && array_key_exists('form_key', $_POST)) { 
    if((new FormIdentifier)->identifyKey($_POST['form_key')) { 
    // identity was verified 
    // validate your form 
    $fv = new FormValidator($_POST); 
    // or whatever .. 
    $fv->validate(); 
    } 
    else { 
    // unable to determine identity 
    // do something silly .. 
    } 
} 

некоторые ноты

  • Ни один из прилагаемого кода был протестирован
  • Важно понимать, что presentation logic должен быть отделен от всех шагов, сделанных здесь.
  • Остановить чтение учебников старше чем 2 года! Если автор не возражает против обновления своего материала, то не против читать его.
+0

Большое вам спасибо, я не могу дождаться, чтобы попробовать это. –

+0

Люди, которые downvote, не оставляя комментарий, должны периодически запрещать этот сайт .. – dbf

1

Расширить формуКлючевой класс?

class B extend formKey{ 
    public function validate($formKey, $oldFormKey) 
    { 
     return $formKey == $oldFormKey; 
    } 
} 

вызов его, как этот

<?php 
if ($_SERVER["REQUEST_METHOD"] == "POST") { 
    $oldFormKey = "abc"; 
    $formKey = new B(); 
    if (!isset($_POST['form_key']) 
     || !$formKey->validate($_POST['form_key'], $oldFormKey)) { 
     //Form key is invalid, show an error 
     $error_msg = 'Security Error.'; 
     $die = "die"; 
    } else { 
     //continue validation 
    } 
} 

Это может быть полезно для вас, и, мне любопытно «По какой-то причине, я не могу изменить переменную класса внутри Validate() метод "

1

для того, чтобы ваши переменные приходят через объект (__construct() до validate()), вам необходимо назначить их в рамках класса, а затем вызвать их из той же области:

class formKey 
    { 
     private $formKey, 
       $old_formKey; 

     public function __construct() 
      { 
       // I just set to false as default 
       $this->old_formKey = false; 
       // Assign here 
       if(isset($_SESSION['form_key'])) 
        $this->old_formKey = $_SESSION['form_key']; 
      } 

     public function validate() 
      { 
       // Use $this-> to recall it from the construct 
       return ($_POST['form_key'] == $this->old_formKey); 
      } 
    } 
+0

ООП-пространство? Что это? – dbf

+0

@dbf Я имею в виду ваш объем. Вы не можете назначить '$ this-> var' в одном методе и попытаться вызвать его с помощью' $ var' в другом. Вам нужно будет вызвать '$ this-> var' в другом методе для доступа к нему. – Rasclatt

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