I have a page with two forms on it (and two submit buttons), and the forms link the page back to itself with action="" for the INSERT INTO statements. One of the INSERT INTO statements is:
<?php
$sql="INSERT INTO panelProduct (length_mm, width_mm, aperture)
VALUES ('$_POST[p_length_mm]','$_POST[p_width_mm]','$_POST[p_aperture]')";
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
echo "1 record added";
?>
One of the reasons I have put the form and the INSERT statements on the same page is that the form allows users to add products to an order, and there may be several products (so I thought the user could keep submitting until they're done...). The other reason was that I need to use a $_POST value sent from the previous page to do something else with the products they enter, and I don't know how to send it to more than one page.
Anyway, the problem I have found is that a new row is inserted into the database every time the page is refreshed, containing NULL values. This makes sense to me as the PHP will execute the statement above every time it encounters it. My question therefore is how I can make some sort of condition that will only execute the INSERT statement if the user enters something in the form and 'Submits'?
you could use the empty() method of PHP to check for null values in each of the variables.
Something like:
if(!empty($_POST['p_length_mm']) && !empty($_POST['p_width_mm']) && !empty($_POST['p_aperture']))
{
//execute your query here
}
else
{
//if there's an alternative you would like to happen if values are null, or just leave out.
}
Hope that does the trick.
You have to check if data come from your form. I'd suggest this approach - name your submit button (i.e. <input type="submit" name="my_submit_button" value="Whatever" /> and this condition to your insert code:
if( isset( $_POST['my_submit_button']) ) {
.. process your post data
}
Also, always remember not to trust user provided data. Verify if all data expected are present in$_POST and format matches requirements (i.e. you ask for number and received letters etc). If all test passed, then you are ready to commit your data to DB.
You need a condition like this:
if ('POST' === $_SERVER['REQUEST_METHOD']) {
// a form was posted
}
Of course, you still need to check whether your post actually contains the right stuff:
isset($_POST['p_length_mm'], $_POST['p_width_mm'], $_POST['p_aperture'])
Even better is to use filter_input_array() to sanitize your incoming data; your current code is open to SQL injection attacks. Using PDO or mysqli and prepared statements is the way to go.
Related
I am just wondering, if possible, the best way to go about allowing users to actually input an SQL query from within a web application.
I have so far got a very simple web application that allows users to view the database tables and manipulate them etc etc..
I wanted to give them an option to actually type queries from within the web app too (SELECT * FROM).. and then display the results in a table. (Exactly the same as a search bar, but I don't think that would cut it, would it?).
I am only using PHP at the moment, is what I'm looking to do possible with just HTML/PHP or will I need the help of other languages?
This may be too complex for me, but if someone could give me a starting point that would be great, thank you.
UPDATE:
From my understanding to answer my question, i need something like:
<form action= Search.php method="POST">
<input type="text" name="Search">
<input type="submit" name"">
Search.php
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$SEARCH = $_POST['Search'];
if (!isset($_POST)) {
$sql = "'%".$_POST['$SEARCH']."%'";
$results = mysqli_query($con, $sql);
echo "<table border ='2'>";
if (mysqli_num_rows($results) !=0) {
while ($row=mysqli_fetch_array($results)) {
echo "<tr><td></td></tr>";
}
echo "</table>";
}else {
echo "Failed! Try another search query.";
}
}
}
?>
At the moment in returns one error:
Undefined index: Search
It's talking about the $SEARCH = $_POST['Search'];
But I thought I am defining that Search, as that's the Search in the form?
Sounds like you're building your own minimalistic version of phpMyAdmin. That's perfectly doable with just PHP and HTML.
A very basic implementation would be a standard HTML form with a textarea, which submits to a PHP script that executes the query and renders a table of the results. You can get the required table column headers from the first result row's array keys if you fetch the results as an associative array.
You may (or perhaps I should say "will") run into situations where users provide a query that returns millions of results. Outputting all of them could cause browsers to hang for long periods of time (or even crash), so you might want to implement some sort of pagination and append a LIMIT clause to the query.
Since the user is providing the SQL query themselves, they need to know what they did wrong so they can correct it themselves as well so you'll want to output the literal error message from MySQL if the query fails.
Allowing users to provide raw SQL queries opens the door to a lot of potential abuse scenarios. If it were my application, I would not want users to use this feature for anything other than SELECT queries, so I would probably have the user-provided queries executed by a MySQL-user that only has SELECT privileges on the application database and not a single other privilege -- that way any user that tries to DROP a table will not be able to.
Undefined index: Search
This error will show only when the PHP is executed for the first time as it's simply expecting "Search" in $_POST.
$_SERVER['REQUEST_METHOD'] checks if the request method is POST it does not check if $_POST have any post data in it.
(Source :$_POST vs. $_SERVER['REQUEST_METHOD'] == 'POST')
But the page is being loading for the first time so it wouldn't have anything in POST.
You can simply avoid it by check if the page is loading for first time, using the "isset()" method.
If its loading for the first time just ignore the further execution of php code and simply show the form to enter the query.
<?php
if(isset($_POST['Search']))
{
`// Query execution code`.
}
?>
<form action= Search.php method="POST">
<input type="text" name="Search">
<input type="submit" name"">
So if the search index is not set in the $_POST it wont execute the php code and will not generate any error.
How can I get back (to the browser) some data automatically (from server) after a POST?
I have a HTML form
I POST the form's data to a php code eg: saveRecord()
the php code saves the data in a mySQL DB
if the data contains a non 0 record ID there will be an UPDATE, if the record ID == 0 there will be an INSERT, and the php code knows (gets back from DB) the new record ID
(after INSTER) how can I send that new record ID back to (browser) HTML form?
If I edit an existing record (ID !=0 ), everithing is fine...
My problem is that, when I post NEW data (ID == 0) I can post it several times, and the php code each time creates a new record in the DB... But I really don't want that. I would like to send (from the server) back (to the browser) the INSERTed records ID (right in the HTML form), to prevent multiple INSERTs...
How can I do that?!
the specific CI code:
function update($record) {
print_r($record);
$id = $record['crn_id'];
$record['crn_active'] = ( ($record['crn_active'] == 'on') ? 1 : 0 );
array_shift($record);
if ($id == 0) {
$this->db->insert('currencies', $record);
} else {
$this->db->where('crn_id', $id);
$this->db->update('currencies', $record);
}
}
?>
Here are three ways to help you on your way that can be generalized:
Make another column unique. If you care so much about possibly having duplicate data in your database there may be some rule to it that you can generalize in the form of a constraint.
Disable the submit button after it was clicked (e.g. <input type="submit" onsubmit="this.disabled=true">). (make sure to re-enable it if some ajax based validation fails)
Use a one time key generated to make sure the user did not just reload the submitted page. Have a look at form keys which can also help against CSRF and XSS attacks.
I have PHP generating an HTML form and I'm trying to write a script that will update the information in the database. For some reason it works on some of the fields and not others.
Code which won't work:
PHP-Form that users can change details within
echo"<form name='details'>";
echo"<p>Surname: <input type='text'id='surname' value='".$row['Surname']."'/></p>;
<p>Telephone: <input type='text'id='phone' value='".$row['Telephone']."'/></p>;
<p>Postcode: <input type='text' id='postcode' value='".$row['Postcode']."'/></p>;
<p>House/Flat Number: <input type='text' id='number' value='".$row['Number']."'/></p>";
AJAX - sends changes to server via querystring
var sname = document.getElementById('surname').value;
var tel = document.getElementById('phone').value;
var num = document.getElementById('number').value;
var pcode = document.getElementById('postcode').value;
var queryString = "?username=" + username +"&email="+email....";
ajaxRequest.open("GET", "url" + queryString, true);
ajaxRequest.send(null);
PHP - execute update command
//connect to server
...
//get variables
$sname = $_GET['sname'];
$pcode = $_GET['pcode'];
$tel = $_GET['tel'];
$num=$_GET['num'];
//process update
$update ="UPDATE User SET Surname='$sname',Telephone='$tel',Number='$num',
Postcode='$pcode' WHERE Username='$username'";
//if query, display success
if(mysqli_query($update))
{
echo"success";
}
else
{
echo"error";
}
//else display error
The query executes fine, but the values aren't displaying within the database. My other variables (username, password etc) all update fine. All database fields are type VARCHAR(80).
EDIT: I do have the query being executed. This still results in the surname, postcode, number and telephone field not being updated.
Ignoring for the moment all the other issues with this code and approach (SQL injection issues, GET vs. POST issue, etc.), and dealing with the update not changing things as expected, there are a couple of things to check.
Try outputing the update query in your logs and make sure that it actually looks like what your expecting. It could be that the values you're meaning to push across the wire are not making it into the query or that.
Verify that running the query by hand in an standalone SQL client (mysql, squirrel, etc...) Actually updates a record. It's entirely possible that a valid update query may not match any records. (Say the username value you're looking for does not match one that's in the database.
Not knowing your infrastructure, I'd suggest some sanity checks: Are you actually pointing at the right database? Do you have a your update wrapped in a transaction that's rolling back? etc ...
A few other tips:
I would suggest looking at PDO, in particular how Prepared Statements work. The kind of query you're building above is someone to run off with all your data or worse. While not a panacea, prepared statements are a solid first step.
Take a look at Jquery's Ajax functions. In particular the post method. It provides a simple interface for making ajax calls without having to construct special url strings. Plus, switching to a POST will avoid your data showing up in webserver logs files.
wondering what the the best way to achieve something is.
To summarise, I have a form that I load by ajax which I use for to both update and insert new rows into a database. To determine whether it is an update or an insert I use the below code (updated forms use the mysql query to populate the form fields).
My code seems sloppy and not best practice. Are there any other suggestion on what would be the best way to do this?
<?
require_once("config.php");
$insert = false;
$update = false;
$targID = 0;
if(isset($_POST['targID'])){
$targID = $_POST['targID'];
$targRow = mysql_fetch_array(mysql_query("select * from events where eventid=$targID"));
$update = true;
}else{
$insert = true;
}
?>
<script type="text/javascript">
var insert = <? echo $insert; ?>+0;
var update = <? echo $update; ?>+0;
......javascript button events, validation etc based on inssert/update
</script>
You already know in the client whether it is an update or an insert, by the fact that you send or do not send the POST data item. So I would write JS in the original page to control the submit and what to do with the data that is sent back. It's difficult to write code without seeing the rest of the page, but at pseudo-code level, you could do the following:
use onsubmit() to catch original submit action
look to see if targID provided
if yes, send update request to server. When row data comes back, fill out form details and display form (you can 'show' a hidden DIV containing the form, for example)
if no - do you need to send anything? - just reveal an empty form (again, show a previously hidden DIV)
Hope this is useful in some way.
You should use native mySQL:
INSERT ... ON DUPLICATE KEY UPDATE
See:
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
What's the point in determining that on the client side? Does it make any difference?
For the server side I'd use $targID passed from the hidden field. if it's greater than zero - update, otherwise - insert.
I have a tabled view in a while loop, where a user can view information on books.
For example, book ISBN, book name, read status...
Basically, when the user sets their 'readstatus' to 'complete' I want that specific table row to become grey! The logic is very straight forward, however I can't get my IF statement to recognise this:
if ($readstatus == 'complete') {
echo '<tr class="completed">';
}
else if ($readstatus != 'complete') {
echo '<tr class="reading">';
}
I'm obviously doing something wrong here, table content to change if the value of 'readstatus' = 'complete', if not, then output is the default
Why are you using $_GET? Does this information come from an HTML form or a URL etc... ?
I suspect you meant to change $readstatus = $_GET['readstatus']; to $readstatus = $row['readstatus'];.
$_GET is an aray of GET parameters which come from the query string.
$row is a row in your database, so if the information is in the database - which I suspect it is - you want to use $row instead of $_GET.
Try changing $readstatus = $_GET['readstatus']; to $readstatus = $row['readstatus'];
The $_GET function relies on the value being contained in the query string of the URL, and it has nothing to do with the database. I have a hunch you're trying to get the value from the database here and you're using the wrong function to do it.
$_GET['readstatus'] says the value is coming from the browser.
$row['readstatus'] says the value is coming from the database.
You need to decide which should take precedence-- probably the $_GET['readstatus']` because it's what the user wants to change. If that's the case, you need to update your database with the new readstatus before you requery the db for the dataset.