I've created mini content management system. Now got afew questions
I'm filtering posts with following function
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;
}
And the PHP code looks like that
$name=filter($_POST['name'], $db);
$title=filter($_POST['title'], $db);
$parent=filter($_POST['parent'],$db);
$switch=filter($_POST['switch'], $db);
if($switch=''){
echo "Return back and select an option";
die();
}
$parentcheck=filter($_POST['parentcheck'],$db);
if($parentcheck=='0')
{
$parent=$parentcheck;
}
$purifier = new HTMLPurifier();
$content = $db->real_escape_string( $purifier->purify( $_POST['content']) );
if(isset($_POST['submit'])&&$_POST['submit']=='Ok'){
$result=$db->query("INSERT INTO menu (parent, name, showinmenu) VALUES ('$parent', '$name', '$switch'") or die($db->error);
$result2=$db->query("INSERT INTO pages (id, title, content) VALUES ('<what?>', '$title', '$content'") or die($db->error);
}
And that's how my tables look like
Table named "pages"
And "menu"
My questions are followings:
I'm trying to get autoincremented id value from menu table after
('$parent', '$name', '$switch'") insertion and set this id in pages table
while inserting ($title, $content). How to do it? Is it possible with single
query?
$content's value is the text with HTML tags. I'm using html purifier.
May I filter it's value too before inserting into db table? Any
suggestion/advice?
Should be
$result2=$db->query("INSERT INTO pages (id, title, content) VALUES (LAST_INSERT_ID(), '$title', '$content'") or die($db->error);
Filtering using real_escape_string( ) should be safe. Is there something else that you want to filter?
Looks like you're using mysqli as the DB library, so you can use $db->insert_id() to retrieve the LAST id created by an insert operation by that particular DB handle. So your queries would become:
$result=$db->query("INSERT INTO menu (parent, name, showinmenu) VALUES ('$parent', '$name', '$switch'") 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);
^^^^^^^
You can't really do it in a single query, as mysql does not make the ID value available for the insert_id function until AFTER the query completes. So you do have to do this in a 3 step process: insert, get id, insert again.
The rule for DB filtering (better known as escaping) is to escape ANYTHING that's user-provided. This even includes data you've retrieve in other db queries and are re-inserting. Escaping isn't really there as a security measure - it's there to make sure that whatever you're putting into the query string doesn't BREAK the query. Preventing SQL injection attacks is just a side effect of this.
Related
I can insert the list of questions but the problem is the answer? How
$myQuery= mysql_query("SELECT * FROM tblquestion, tblanswer WHERE questionID='$ctrlnum'");
$numRows = mysql_num_rows($myQuery);
then this will be the insertion of record:
$myQuery = mysql_query("INSERT INTO tblquestion VALUES ( '$ctrlnum','$question1','$question2','$question3','$question4','$question5',
'$question6','$question7','$question8','$question9','$question10') ");
$myQuery= mysql_query("INSERT INTO tblprelimanswer VALUES ('$ctrlnum','$answer1','$answer2','$answer3','$answer4','$answer5', '$answer6','$answer7','$answer8','$answer9','$answer10')
");
How can I insert the answers?
Change the code to
$myQuery = mysql_query("INSERT INTO tblquestion VALUES ($ctrlnum','$question1','$question2','$question3','$question4','$question5','$question6','$question7','$question8','$question9','$question10') ") or die (mysql_error());
$myQuery= mysql_query("INSERT INTO tblprelimanswer VALUES ('$ctrlnum','$answer1','$answer2','$answer3','$answer4','$answer5', '$answer6','$answer7','$answer8','$answer9','$answer10')") or die (mysql_error());
and post back what your error messages are
(This should be a comment but its rather long and easier to read with formatting)
While using a statement of the form
INSERT INTO tblquestion VALUES (...)
will work in MySQL, it is very bad practice not to explicitly state what columns each value maps to. e.g.
INSERT INTO tblquestion ( someId, avalue, adifferentthing ) VALUES (...)
In the relational database model, there is no concept of oredering of attributes within a record. Even on MySQL where such an approach is possible, semantic value is lost by omitting the atribute list and there is a risk of bugs being introduced if the schema is modified.
Further:
'$question1','$question2','$question3','$question4','$question5'....
implies that your data is not normalized. Each question should be in a seperate row.
<html>
<head>
HTML CODE
<?
$username="xxxxxx";
$password="xxxxxx";
$database="xxxxxx";
mysql_connect(localhost,$username,$password);
$escape = "INSERT INTO monster VALUES ('',$_POST["name"],$_POST["soort"])";
$escape2 = "DELETE monster FROM monster LEFT OUTER JOIN (
SELECT MIN( ID ) AS ID, NAME, PREF
FROM monster
GROUP BY NAME, PREF
) AS KeepRows ON monster.ID = KeepRows.ID
WHERE KeepRows.ID IS NULL";
$query=mysql_real_escape_string($escape);
$query2=mysql_real_escape_string($escape2);
#mysql_select_db($database) or die("MySQL error: Kan inte ansluta till databasen.");
mysql_close();
?>
</body>
</html>
Every time i run this(from another file, containing the name and soort post's) I get an 500 internal server error. First I figured that the queries may be the problem, but they don't even get executed. However, i tried to escape the queries. But still error.
What is wrong with this code? (note: $escape2 is some code i found that removes duplicates in the database. But i don't really know how to format it so that it can be used through php.)
Use something like below...
$query = "INSERT INTO monster VALUES ('', '".$_POST["name"]."', '".$_POST["soort"]."')";
Please do not insert values without escaping.
problem in insert into statement
it should be
$escape = "INSERT INTO monster VALUES ('',".$_POST['name'].",".$_POST['soort'].")";
it is preferable to write colums name while writing insert queries
if column contains string values like VARCHAR or TEXT then use quoted_printable_decode
pass null if column is autoincrement
insert statment
$escape = "INSERT INTO monster (col1, col2, col3) VALUES (NULL,'".$_POST['name']."',".$_POST['soort'].")";
or
$escape = "INSERT INTO monster (col2, col3) VALUES ('".$_POST['name']."',".$_POST['soort'].")";
It looks like you need something like this:
$query = "INSERT INTO monster VALUES ('', '".$_POST["name"]."', '".$_POST["soort"]."')";
Also I would suggest to use prepared statements because it is bad experience to build queries.
First of all I have cool proposition for you. What do you say about some advanced PHP? One step further into great world of safe PHP + MySQL apps?
Introducting to you a PDO. (I know this is not answer to your question but you can consider it). Example of use on your queries:
$db = new PDO('mysql:host=localhost;dbname='.$database, $username, $password);
$insertQuery = $db->prepare('INSERT INTO monster VALUES ("", :name, :soort)');
$deleteQuery = $db->prepare('DELETE monster FROM monster LEFT OUTER JOIN (
SELECT MIN( ID ) AS ID, NAME, PREF
FROM monster
GROUP BY NAME, PREF
) AS KeepRows ON monster.ID = KeepRows.ID
WHERE KeepRows.ID IS NULL');
//to execute query:
$deleteQuery->execute();
//or with params:
$insertQuery->execute(array(
':name' => $_POST['name'],
':soort' => $_POST['soort'],
));
Cool, huh? There is more... Now according to your problem it could be everything (as we don't have error log) but my guess is:
Try to use <?php instead of <?
$escape = "INSERT INTO monster VALUES ('',{$_POST["name"]},{$_POST["soort"]})";
EDIT:
As you provided error log - now I'm sure that problem is in $escape query. It's because you used $escape = " <- and then $_POST["name"] so there was a collision of " (if I can say so).
Try this:
Whenever you insert string type of values in the database using query it has to pass in the quote format. So you just need to change your insert query here.
$query = "INSERT INTO monster VALUES ('', '".$_POST["name"]."', '".$_POST["soort"]."')";
write query like this.
-
Thanks
I want to insert data from one table into another where one field equals another in both tables. So far this works. The problem is, I also need to insert additional data into those same rows that is not included on the first table.
//enter rows into database
foreach($_POST['sku'] as $row=>$sku)
{
//this is the data that needs to be added to the table
$item_sku=$sku;
$image="/$item_sku.jpg";
$small_image="/$item_sku.jpg";
$thumbnail="/$item_sku.jpg";
//currently this is what is working to import data from one table to the other
$sql= "INSERT INTO magento_import (sku, description, price)
SELECT PR_SKU, PR_Description, PR_UnitPrice
FROM products
WHERE PR_SKU = '$sku'";
//I need something here to add the above variables to the same row where PR_SKU = '$sku'
if (!mysql_query($sql))
{
die('Error: '.mysql_error());
}
echo "$row record added";
}
The columns for the missing data on magento_table are called 'image', 'small_image', and 'thumbnail'. This is simple a hack to put data from an old product table into a new product table, export as a CSV, and run a profile in Magento. I don't need to worry about SQL injections. It's something I'm running off of a local machine. I'm trying to avoid as much manual data entry as possible while switching products over to a new ecommerce system. Thanks for any help you can give.
Selecting literal values should do what you intend:
$sql= "INSERT INTO magento_import (sku, description, price, image, small_image, thumbnail)
SELECT PR_SKU, PR_Description, PR_UnitPrice, \"$image\", \"$small_image\", \"$thumbnail\"
FROM products
WHERE PR_SKU = '$sku'";
You can use another update statement to do this. I doubt if you can do this with one single query
foreach($_POST['sku'] as $row=>$sku)
{
//this is the data that needs to be added to the table
$item_sku=$sku;
$image="/$item_sku.jpg";
$small_image="/$item_sku.jpg";
$thumbnail="/$item_sku.jpg";
//currently this is what is working to import data from one table to the other
$sql= "INSERT INTO magento_import (sku, description, price)
SELECT PR_SKU, PR_Description, PR_UnitPrice
FROM products
WHERE PR_SKU = '$sku'";
//I need something here to add the above variables to the same row where PR_SKU = '$sku'
if (!mysql_query($sql))
{
die('Error: '.mysql_error());
}else {
$sql = "UPDATE magento_import SET item='$item',image='$image',small_image='$small_image',thumbnail='$thumbnail' WHERE PR_SKU = '$sku'";
echo "$row record added";
}
}
You can just add the variables directly to the query. As long as they are quoted they will work as simple values.
$sql= "INSERT INTO magento_import (sku, description, price, x, y, z)
SELECT PR_SKU, PR_Description, PR_UnitPrice, '$x' AS x, '$y' AS y, '$z' AS z
FROM products
WHERE PR_SKU = '$sku'";
I want to build a query to insert photo details in database tables. Here's my tables structure:
photos(photo_id, photo_title, caption, ....)
tags(tag_id, tag_name)
tag_asc(tag_id, photo_id)
A photo has title, caption, and tags array. I want to:
Insert photo_title and caption in photos table.
Insert each of tag from tags array in tags table.
Insert tag_id and photo_id in tag_asc table (to link tags with photos).
I have come up with following three queries to do above task.
mysql_query("INSERT INTO photos (photo_title, caption)
VALUES ($title, $caption)");
$photo_id = mysql_insert_id(); //get photo_id
foreach ($tags as $tag){
mysql_query("INSERT INTO tags (tag_name)
VALUES ($tag)");
$tag_id = mysql_insert_id(); //get tag_id
mysql_query("INSERT INTO tag_asc (tag_id, photo_id)
VALUES ($tag_id, $photo_id)");
}
My question
If the above approach is good, or if there is more efficient way to do same thing?
Most of what you're doing looks fine. The main problem I see is the potential for duplicate tags.
It would be better to check if a tag exists and fetch the existing tag's ID if it does, rather than creating a new tag each time. This would prevent duplicate tag names from being inserted into the tags table. If you know each tag is unique, this could speed things up later — for example, you could search photos by their tag IDs rather than having to do some messy JOIN stuff.
Give tags.tag_name a unique index if it doesn't have one already.
Use the following function to fetch a tag ID. If the tag already exists, the existing row ID will be returned. If not, a new row will be created and its ID will be returned.
-
function select_or_create_tag($tag_name) {
$tag_name = addslashes($tag_name);
$result = mysql_query("SELECT id FROM tags WHERE tag_name='$tag_name'");
if ( mysql_num_rows($result) > 0 )
return mysql_result($result, 0, 0);
$insert = mysql_query("INSERT INTO tags (tag_name) VALUES ('$tag_name')");
return mysql_insert_id($insert);
}
Example usage, based on your code:
mysql_query("INSERT INTO photos (photo_title, caption)
VALUES ($title, $caption)");
$photo_id = mysql_insert_id();
foreach ( $tags as $tag ) {
$tag_id = select_or_create_tag($tag);
mysql_query("INSERT INTO tag_asc (tag_id, photo_id)
VALUES ($tag_id, $photo_id)");
}
Also:
Make sure you have non-unique indices set up on tag_asc.tag_id and tag_asc.photo_id for faster querying.
As OMG Ponies mentioned, it might be worth converting this code to a stored SQL procedure. That would get rid of a lot of the overhead involved with making all these SQL queries individually.
I have an enrollment form which takes consumer information, stores it in session, passes from page to page then stores in a database when finished. Originally the table simply listed fields for up to 16 persons but after reading into relational databases, found this was foolish.
I have since created a table named "members" and "managers". Each enrollment will take the information input, store the manager ID in the respective table and place a reference field in each member row containing the manager ID.
While I allow up to 16 members to be enrolled at once, this can range from 1-16.
My best guess is to use a FOR-loop to run though multiple INSERT statements in the event more than 1 member is enrolled.
In the example below, I am using the variable $num to represent the individual member's information and $total to represent the number of all members being enrolled. The code here does not function but am looking for:
a) ways to correct
b) understand if there are more 'efficient' ways of doing this type of INSERT
sample code:
<?php
$conn = mysql_connect("localhost", "username", "pw");
mysql_select_db("db",$conn);
for ($num=1; $num<=$total; $num++) {
$sql = "INSERT INTO table VALUES ('', '$clean_f'.$num.'fname', '$clean_f.$num.mi', '$clean_f.$num.lname', '$clean_f.$num.fednum', '$clean_f.$num.dob', '$clean_f.$num.ssn', '$clean_f.$num.address', '$clean_f.$num.city', '$clean_f.$num.state', '$clean_f.$num.zip', '$clean_f.$num.phone', '$clean_f.$num.email')";
$result = mysql_query($sql, $conn) or die(mysql_error());
}
mysql_close($conn);
header("Location: completed.php");
?>
If all of your statements are structurally the same, but with different parameter values, consider using the PDO extension, which supports prepared statements. The benefits of prepared statements can be read here (http://www.php.net/manual/en/pdo.prepared-statements.php), but in general, the same statement will only need to be compiled once, but can be executed as many times as you want with different parameters, which can make your script more "efficient".
Using PDO, your code could look something like:
$db = new PDO('mysql:host=localhost;dbname=db', 'username', 'pw');
$statement = $db->prepare('INSERT INTO tablename (field1, field2, field3, ...) VALUES (?,?,?,?');
for ($num=1; $num<=$total; $num++) {
$statement->execute(array('val1', 'val2', 'val3', '...'));
}
Generally, putting a query in a loop is bad thing. There is usually a better way. In this case, you should use the multi-insert syntax. Your INSERT isn't working because you didn't specify the fields. I'm assuming the lack of a space between the table name and VALUES is a typo, along with the bad quoting.
INSERT INTO table_name (field1, fname, lname, fednum, ...)
VALUES ('val1', 'Pete', 'Moss', 1234),
('val2', 'T.', 'Cupp', 54321),
('val3', 'Youdid', 'Watt', 787123);
The solution, if I read you right, is to start with the fixed query string:
$queryString = "INSERT INTO table (field1, field2, ...) VALUES ";
then run a loop to build the malleable part. Putting your values into arrays makes things easier:
$queryInsert = '';
$total = count($value1Array);
while ($i < $total) {
$queryInsert .= "('$value1Array[$i]','$value2Array[$i]','$value3Array[$i],...), ";
++$i;
}
then append to the first query piece:
$queryString = $queryString.$queryInsert;
and trim off the trailing , and you're good to go.