开发者

PHP form submission

I've built mini content management system. In my page add form i'm using ckeditor. for text are named content

<textarea id="content" style="width:100%" name="content"></textarea>

Adding all data from form into db table with following php code. (Function filter used for sanitizing data)

<?php
require '../../core/includes/common.php';

$name=filter($_POST['name'], $db);
$title=filter($_POST['title'], $db);
$parentcheck=filter($_POST['parentcheck'],$db);
if(isset ($_POST['parent'])) $parent=filter($_POST['parent'],$db);
else $parent=$parentcheck;  
$menu=filter($_POST['menu'], $db);
$content = $db->escape_string($_POST['content']);

if(isset($_POST['submit'])&&$_POST['submit']=='ok'){
$result=$db->query("INSERT INTO menu (parent, name, showinmenu) VALUES ('$parent', '$name', '$menu')") or die($db->error);
$new_id = $db->insert_id;
$result2=$db->query("INSERT INTO pages (id, title, content) VALUES ('$ne开发者_开发技巧w_id', '$title', '$content')") or die($db->error);  
header("location:".$wsurl."admin/?page=add");       
}
?>

FUNCTION FILTER (data sanitization)

function filter($data, $db)
{
    $data = trim(htmlentities(strip_tags($data)));
    if (get_magic_quotes_gpc())
    $data = stripslashes($data);
    $data = $db->escape_string($data);
    return $data;
}

I got questions about it. (I'm newbie to ajax.)


  1. Currently i'm submitting data with standart php (page refreshes every time). How to modify code for ajax submission?
  2. I have only one button for submitting data. I want to create second button "save" which will update db fields via ajax
  3. How can i create autosave function (which periodically saves form in the background and informss user about it, just like on Stackoverflow) via ajax?

Thx in advance


Let's suppose you want to use jQuery to do the ajax business for you, you need to setup a periodic POST of the data in the textarea (note that in some browsers GET requests have a limit).

On the first POST, you need to tell the PHP script "this is the first POST" so that it knows to INSERT the data, it should then return to you some identifying characteristic. Every other time you POST data, you should also send this identifying characteristic, let's just use the primary key (PK). When you POST data + PK, the PHP script should run an update query on the SQL.

When constructing these, the thing to think about is sending data from the browser using JavaScript to a PHP script. The PHP script gets only whatever packet of data you send, and it can return values by producing, for instance, JSON. Your JavaScript code can then use those return values to decide what to do next. Many beginners often make the mistake of thinking the PHP can make calls to the JS, but in reality it's the other way around, always start, here, with the JS.

In this instance, the PHP is going to save data in the database for you, so you need to ship all the data you need to save to the PHP. In JS, this is like having some magic function you call "saveMyData", in PHP, it's just like processing a form submission.

The JavaScript side of this looks something like this (untested):

<script type="text/javascript">
    var postUpdate = function(postKey){
        postKey = postKey || -1;
        $.post("/myscript.php", 
               /* note that you need to send some other form stuff
                  here that I've omitted for brevity */
               { data: $("#content").value(), key: postKey }, 
               function(reply){
                   if(reply.key){
                       // if we got a response containing the primary key
                       // then we can schedule the next update in 1s
                       setTimeout(function(){postUpdate(reply.key);}, "1000");
                   }
               }
        });
    };
    // first invocation:
    postUpdate();
</script>

The PHP side will look something like this (untested):

Aside: your implementation of filter should use mysql_real_escape_string() instead of striptags, mysql_real_escape_string will provide precisely the escaping you need.

<?php
require '../../core/includes/common.php';

$name = filter($_POST['name'], $db);
$title = filter($_POST['title'], $db);
$parentcheck = filter($_POST['parentcheck'],$db);
if(isset($_POST['parent'])){
    $parent = filter($_POST['parent'],$db);
}else{
    $parent = $parentcheck;
}
$menu = filter($_POST['menu'], $db);
$content = $db->escape_string($_POST['content']);

$pk = intval($_POST['key']);

if($pk == -1 || (isset($_POST['submit']) && $_POST['submit']=='ok')){
    $result = $db->query("INSERT INTO menu (parent, name, showinmenu) VALUES ('$parent', '$name', '$menu')") 
              or die($db->error);
    $new_id = $db->insert_id;
    $result2 = $db->query("INSERT INTO pages (id, title, content) VALUES ('$new_id', '$title', '$content')") 
               or die($db->error);
    $pk = $db->insert_id;
    echo "{\"key\": ${pk}}";
    // header("location:".$wsurl."admin/?page=add");       
}else if($pk > 0){
     $result2 = $db->query("UPDATE pages SET content='$content' WHERE id='$pk')") 
               or die($db->error);
     echo "{\"key\": ${pk}}";
}


For AJAX, you can use jQuery's ajax API. It is very good and is cross-browser. And for saving and auto-saving: you can use a temporary table to store your data. When the user presses the save button or when your data is auto-saved, you save your data to the table using AJAX and return a key for the newly created row. Upon future auto-save/save button events, you update the temporary table using AJAX.

And one word of advice, use a framework for your PHP and Javascript. I personally use Symfony and Backbone.js. Symfony checks for CSRF and XSS automatically and using Doctrine prevents SQL-injection too. There are other frameworks available (such as CodeIgniter, CakePHP and etc.) but I think Symfony is the best.

Edit: For the auto-save functionality, you can use Javascript SetTimeout to call your AJAX save function, when the page loads for the first time.


With regard to security issues:

Your silver bullet function is fundamentally flawed, it does not work, will never work and can never work.

SQL has different escaping needs than hmtl.
The functions you use counteract each other. escape_string adds \, stripslashes removes them.
Never mind the order of the functions, you need to use a specialized escape function for one and only one purpose.
On top of that you are using depreciated functions.

For MySQL this is mysql_real_escape_string. Note that escape_string (without the real) is depreciated, because it is not thorough enough. Use real_escape_string instead. On mysqli escape_string is an alias for real_escape_string.

See:
How does the SQL injection from the "Bobby Tables" XKCD comic work?
The ultimate clean/secure function

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜