редактирование таблицы MySQL с HTML-формой - PullRequest
1 голос
/ 09 октября 2009

Моя цель - создать простую CMS на основе форм, чтобы клиент мог войти в систему и редактировать данные таблицы MySQL через HTML-форму. Логин работает, но страница редактирования не возвращает значения из таблицы MySQL, и при этом я не получаю никаких ошибок.

Я все еще любитель, и я сначала запустил следующий код для проекта класса, но теперь планирую реализовать его для живого сайта. Из того, что я понимаю, мне не нужно объявлять следующий / предыдущий / и т. Д. переменные вверху, которые я все равно безуспешно пытался сделать. Что-нибудь выделяется среди вас?:

<?php

echo "<h2>Edit Special Offer</h2><hr>";

if (isset($_COOKIE["username"]))
    {
    echo "Welcome " . $_COOKIE["username"] . "!<br />";
    include "login.php";
    }
else
  echo "You need to log in to access this page.<br />";


if(isset($previous))
{
$query = "SELECT id, specialtitle, specialinfo
FROM special WHERE id < $id ORDER BY id DESC";
$result = mysql_query($query);
check_mysql();
$row = mysql_fetch_row($result);
check_mysql();
if ($row[0] > 0)
{
$id = $row[0];
$specialtitle = $row[1];
$specialinfo = $row[2];
}
}


elseif (isset($next))
{
$query = "SELECT id, specialtitle, specialinfo
FROM special WHERE id > $id ORDER BY id ASC";
$result = mysql_query($query);
check_mysql();
$row = mysql_fetch_row($result);
check_mysql();
if ($row[0] > 0)
{
$id = $row[0];
$specialtitle = $row[1];
$specialinfo = $row[2];
}
}



elseif (isset($add))
{
$query = "INSERT INTO special (specialtitle, specialinfo)
VALUES ('$specialtitle', '$specialinfo')";
$result = mysql_query($query);
check_mysql();
$id = mysql_insert_id();
$message = "Special Offer Added";
}


elseif (isset($update))
{
$query = "UPDATE special
SET specialtitle='$specialtitle', specialinfo='$specialinfo'
WHERE id = $id";
$result = mysql_query($query);
check_mysql();
$id = mysql_insert_id();
$message = "Monthly Special Updated";
}


elseif (isset($delete))
{
$query = "DELETE FROM special WHERE id = $id";
$result = mysql_query($query);
check_mysql();
$specialtitle = "";
$specialinfo = "";
$message = "Special Offer Deleted";
}
$specialtitle = trim($specialtitle);
$specialinfo = trim($specialinfo);
?>



<form method="post" action="editspecial.php">
<p><b>Special Offer</b>
<br><input type="text" name="specialtitle" <?php echo "VALUE=\"$specialtitle\"" ?>> </p>

<p><b>Special Info/Description</b>
<br><textarea name="specialinfo" rows="8" cols="70" >
<?php echo $specialinfo ?>
</textarea> </p>

<br>
<input type="submit" name="previous" value="previous">
<input type="submit" name="next" value="next">
<br><br>
<input type="submit" name="add" value="Add">
<input type="submit" name="update" value="Update">
<input type="submit" name="delete" value="Delete">
<input type="hidden" name="id" <?php echo "VALUE=\"$id\"" ?>>
</form>
<?php
if (isset($message))
{
echo "<br>$message";
}
?>

login.php:

<?php

function check_mysql()
{
if(mysql_errno()>0)
{
die ("<br>" . mysql_errno().": ".mysql_error()."<br>");
}
}
$dbh=mysql_connect ("xxxxxxxxxxxxxxxxx","xxxxxxxx","xxxxxxxx");
if (!$dbh)
{
die ("Failed to open the Database");
}
mysql_select_db("xxxxxx");
check_mysql();
if(!isset($id))
{
$id=0;
}

?>

Ответы [ 4 ]

3 голосов
/ 09 октября 2009

Пожалуйста, пожалуйста, сделайте немного больше обучения, прежде чем пытаться построить эту вещь. Вы можете сделать это так, как вы это делаете, но только с небольшим дополнительным знанием о ОО-программировании, и, возможно, о классах Pearl db у вас будет 3x более чистый код.

Если вы действительно не хотите, по крайней мере, извлекать каждую из ваших процедур сохранения, обновления, удаления и т. Д. В функции, а не просто вставлять их в свой код. поместите их в отдельный файл и включите в эту страницу.

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

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

<?php
// Subclass this class and implement the abstract functions to give access to your table
class ActiveRecordOrder
{

    function ActiveRecordOrder()
    {
    }

    //Abstract function should return the table column names excluding PK
    function getDataFields()
    {}

    //Abstract function should return the primary key column (usually an int)
    function getKeyField()
    {}

    //abstract function just return the table name from the DB table
    function getTableName() 
    {}

    /*
    This function takes an array of fieldName indexed values, and loads only the
    ones specified by the object as valid dataFields.
    */
    function loadRecordWithDataFields($dataRecord)
    {
        $dataFields = $this->getDataFields();
        $dataFields[] = $this->getKeyField();
        foreach($dataFields as $fieldName)
        {
            $this->$fieldName = $dataRecord[$fieldName];
        }
    }

    function getRecordsByKey($keyID, &$dbHandle)
    {
        $tableName = $this->getTableName();
        $keyField  = $this->getKeyField();
        $dataFields = $this->getDataFields();
        $dataFields[] = $this->getKeyField();

        $results = $dbHandle->select($tableName, $dataFields, array($keyField => $keyID));

        return $results;
    }

    function search($whereArray, &$dbHandle)
    {
        $tableName = $this->getTableName();
        $dataFields = $this->getDataFields();
        $dataFields[] = $this->getKeyField();
        return  $dbHandle->select($tableName, $dataFields, $whereArray);
    }

    /**
    * Since it is *hard* to serialize classes and make sure a class def shows up
    * on the other end. this function can just return the class data.
    */
    function getDataFieldsInArray()
    {
        $dataFields = $this->getDataFields();
        foreach($dataFields as $dataField)
        {
            $returnArray[$dataField] = $this->$dataField;
        }
        return $returnArray;
    }

    /**
    * Added update support to allow to update the status
    * 
    * @deprecated - use new function saveObject as of 8-10-2006 zak
    */
    function updateObject(&$dbHandle)
    {

        $tableName = $this->getTableName();
        $keyField = $this->getKeyField();
        $dataArray = $this->getDataFieldsInArray();

        $updatedRows = $dbHandle->updateRow(
            $tableName,
            $dataArray, 
            array( $keyField => $this->$keyField )
        );

        return $updatedRows;
    }   

    /**
    * Allows the object to be saved to the database, even if it didn't exist in the DB before.
    * 
    * @param mixed $dbhandle
    */
    function saveObject(&$dbhandle)
    {
        $tableName = $this->getTableName();
        $keyField = $this->getKeyField();
        $dataArray = $this->getDataFieldsInArray();

        $updatedRows = $dbHandle->updateOrInsert(
            $tableName,
            $dataArray, 
            array( $keyField => $this->$keyField )
        );

        return $updatedRows;
    }   
}
1 голос
/ 09 октября 2009

Будьте осторожны с вашим кодом там. Вы не фильтруете значение cookie и не должны хранить имя пользователя непосредственно там, поскольку оно может быть легко изменено посетителем. Вам следует заглянуть в filter_input для фильтрации данных cookie и всех данных формы, которые отправляются, особенно вашего $ _POST ['id']

это избавит вас от душевных страданий от атак.

Ваши операторы if else проверяют, установлены ли переменные, но вы не устанавливаете следующее, предыдущее, добавляете и т. Д.

Вы используете кнопки отправки с этими значениями, поэтому вам нужно будет проверить

if(isset($_POST['previous']))

вместо твоего, который

if(isset($previous))

Я не вижу, где вы задаете данные своей базы данных, если у вас нет файла, который вы не опубликовали. (не публиковать реальные, конечно, но я ничего не вижу)

1 голос
/ 09 октября 2009
"Welcome " . $_COOKIE["username"] . "!<br />"; [and many other places]

HTML-инъекция, приводящая к дырам в безопасности сайта. Вам нужно использовать htmlspecialchars каждый раз, когда вы выводите текстовое значение в HTML.

"INSERT INTO special (specialtitle, specialinfo) VALUES ('$specialtitle'  [and many other places]

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

if (isset($_COOKIE["username"]))

Файлы cookie не защищены, любой может установить файл cookie username на стороне клиента. Не используйте его для контроля доступа, только как ключ к сохраненному идентификатору пользователя или идентификатору сеанса.

Вы также, похоже, используете register_globals для доступа к значениям $ _REQUEST в качестве прямых переменных. Это еще один крайний нет-нет.

Между всеми этими мошенниками в области безопасности вы - легкая утка для русских хакеров, которые захватят ваш сайт для распространения вирусов и спама.

1 голос
/ 09 октября 2009

Я не знаю, что происходит в login.php, но вы используете $ id до его установки. Это только в первой части.

Редактировать: Чтобы уточнить, вы используете $ id в каждом операторе запроса и устанавливаете его впоследствии, я думаю, что $ id равен нулю, и поэтому ничего не возвращается.

Редактировать 2: Что еще происходит в login.php? Если вы никогда не читаете переменные $ _POST, ничего не произойдет.

Редактировать 3: Как я уже частично сказал в комментарии, ваш if (isset ($ previous)) раздел, elseif (isset ($ update)) section и elseif (isset ($ delete)) section никогда ничего не сделает, так как $ id всегда равно 0.

После аутентификации вашего пользователя вам нужно получить и отфильтровать опубликованных переменных, $ _POST ['id'], $ _POST ['previous'] и т. Д.

...