I am coding a discography tool for a music database.
Artists are able to insert tracks, singles, EPs, and albums all into separate tables on the database.
Having tracks be in their own separate table allows the same tracks to be attached to multiple singles, EPs and albums while only requiring there to be one record for that track in the database.
Which means individual track pages can have an automatically generated list of links back to the Singles, EPs and albums that they appear on. Making navigating the database through the website a much smoother experience.
I have come to the point where I am coding a tool to attach any existing tracks in the database for a given artist onto an album page.
I am using another table in the database called 'trackconnections' to create the relational links between the track ids from the track table and the album id from the album table, with an additional column called albumtracknum available to be able to output the tracks in the right order when queried on the album page.
The code for the tool is behind a button labelled 'Attach existing track(s) to album'. The code for this tool is as follows:
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "includes/db_connect.pdo.php";
$artistid = $_POST["artistid"];
$albumid = $_POST["albumid"];
echo '<strong>Select each track you would like to add to this album below and type in the track number you want it to have on the album in the box underneith the name of each selected track.</strong><br><br>';
$stmt = $pdo->query("SELECT * FROM track WHERE artist_id = '$artistid'
order by trackname");
while ($row = $stmt->fetch())
{
echo '<form action="includes/attachexistingtracktoalbum.inc.php" method = "post">';
echo '<div class="checkbox">';
echo '<label>';
echo "<input type='checkbox' name='trackid[]' value='".$row['id']."' />";
echo '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
echo ' '.$row['trackname'];
echo '</label>';
echo "<br><label for='albumtracknum'>Track number:</label><br>
<input type='text' name='albumtracknum[]'>
<input type='hidden' name='albumid[]' value='".$albumid,"'>
<br><br>";
echo '</div>';
}
?>
<input type="hidden" name="albumidforreturn" value="<?php echo $albumid;?>">
<button type="submit" name="attachexistingtracktoalbum-submit">Attach track(s) to album</button>
<?php }
else {
header("Location: /index.php");
exit();
}?>
(NB: The post data here is not sanitised for the sql query as it has been passed along in a hidden form from the original album page)
This generates a page with all track names for the current artist available on a list with checkboxes, with each track name being followed by a data entry box to enter the track number for the album being added to.
Submission of the form then hands off to the following include code:
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "db_connect.pdo.php";
$albumid = implode(',',$_POST['albumid']);
$trackid = implode(',',$_POST['trackid']);
$albumtracknum = implode(',',$_POST['albumtracknum']);
$albumidforreturn = $_POST['albumidforreturn'];
// echo 'albumid: '.$albumid.'<br>';
// echo 'trackid: '.$trackid.'<br>';
// echo 'albumtracknum: '.$albumtracknum.'<br>';
$sql = "INSERT INTO trackconnections (albumid, trackid, albumtracknum) VALUES (?,?,?);";
$stmt= $pdo->prepare($sql);
$stmt->execute([$albumid,$trackid,$albumtracknum]);
header("Location: ../albumdetail.php?albumid=$albumidforreturn");
exit();
}
else {
header("Location: ../index.php");
exit();
}
(NB: The commented out echos are there to test what the output is from the previous form)
The 2 problems I am having are that my 'Attach existing tracks to album' form submit:
1. Passes on too much data.
The generated form should only pass on the track ids, album number, and track numbers that have had their checkboxes ticked. For insertion into the 'trackconnections' table.
Instead it narrows down the ticked checkbox track ids only and then creates comma separated values for every available track to select, rather than just those actually selected.
Which leads to annoying outputs such as the following when passing on data from form to include:
albumid: 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
trackid: 30,14
albumtracknum: ,2,3,,,,,,,,,,,,,,,,,,,,,
Where it should only read as:
albumid: 4,4
trackid: 30,14
albumtracknum: 2,3
Having too much data get passed through means that the row inserts won't be correct on multiple INSERTS once I do get this working, as they won't align with one another in the correct order.
2. The include only INSERTS 1 row to the 'trackconnections' table.
It seems I am misunderstanding how to add multiple rows to the database with my code here.
As having multiple checkboxes ticked on my 'Attach existing tracks to album' form only inserts 1 single row to the database on submission of the form each time.
Consistently the only track that gets added to the 'trackconnections' table is the first track with its checkbox ticked and, because of issue no. 1 above, the albumtracknum is always 0 unless I type a number into the first albumtracknum box on the available checklist.
I need to make tweaks to this code so that both problem 1 and 2 are addressed together, meaning that ticking the checkboxes & adding track numbers into each box following the track names actually adds multiple rows to the database along with their corresponding album track numbers.
I hope someone can help.
EDIT TO SHOW REFINED AND WORKING CODE:
New code for checkbox and textbox sections -
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "includes/db_connect.pdo.php";
$artistid = $_POST["artistid"];
$albumid = $_POST["albumid"];
echo '<strong>Select each track you would like to add to this album below and type in the track number you want it to have on the album in the box underneith the name of each selected track.</strong><br><br>';
$stmt = $pdo->query("SELECT * FROM track WHERE artist_id = '$artistid'
order by trackname");
echo '<form action="includes/attachexistingtracktoalbum.inc.php" method = "post">';
while ($row = $stmt->fetch())
{
echo '<div class="checkbox">';
echo '<label>';
echo "<input type='checkbox' name='trackid[]' value='".$row['id']."' />";
echo '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
echo ' '.$row['trackname'];
echo '</label>';
echo "<br><label for='albumtracknumber'>Track number:</label><br>
<input type='text' name='albumtracknumber_".$row['id']."'>
<input type='hidden' name='albumid[]' value='".$albumid,"'>
<br><br>";
echo '</div>';
}
?>
<input type="hidden" name="albumidforreturn" value="<?php echo $albumid;?>">
<button type="submit" name="attachexistingtracktoalbum-submit">Attach track(s) to album</button>
</form>
<?php }
else {
header("Location: /index.php");
exit();
}
New code for the include INSERT processing -
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "db_connect.pdo.php";
$albumid = implode(',',$_POST['albumid']);
$trackid = implode(',',$_POST['trackid']);
$albumidforreturn = $_POST['albumidforreturn'];
foreach($_POST['trackid'] as $trackidloop) {
$albumtracknum = $_POST["albumtracknumber_{$trackidloop}"];
$sql = "INSERT INTO trackconnections (albumid, trackid, albumtracknum) VALUES (?,?,?);";
$stmt= $pdo->prepare($sql);
$stmt->execute([$albumid,$trackidloop,$albumtracknum]);
}
header("Location: ../albumdetail.php?albumid=$albumidforreturn");
exit();
}
else {
header("Location: ../index.php");
exit();
}
This isn't an entire solution but I see some problems:
You are looping through tracks and creating a new form for each one. The first problem is , you are missing the closing form tag. I guess the browser is automatically creating one, when it sees the next form start tag. ?? That's why you only get one single posted checkbox.
I would put all the track checkboxes into a single form. Then the posted trackid[] array will contain all the checked items.
[EDIT after your comment: The hidden fields albumid[] post the entire array, whereas the trackid[] checkboxes only post the actual checked boxes (HTML spec).
Instead of having albumid[], You could put the trackID and albumID together for the checkbox value, then parse them apart when you handle the post:
$value = $row['id']. ',' . $row['albumid'];
echo "<input type='checkbox' name='trackid[]' value='".$value."' />";
ALSO, the SQL, "INSERT INTO (..) .. VALUES (...) " only inserts one row.
It's easy to do that SQL in a loop for all the checked boxes.
foreach($_POST['trackid'] as $value) {
// parse the $value...
// SQL Insert...
}
EDIT 2: From my own comment:
Like hidden fields, input (text) field arrays also post the entire array (with empty values for blank inputs). (Again, this is not a PHP thing, it's a web browser standard to only post checked checkboxes and radio buttons. But ALL text and hidden INPUTs are posted.) So in your example, you need to code a mechanism to know which textbox goes with each checkbox. Quick and dirty...You could add a row index (0,1,2,3...) as another comma-separated number in your checkbox values, then you'll have the index into the posted textbox array. Alternatively, you could name the textboxes ' .. name="textinput_' . $row['trackid'] . '" ...' (not an array), then upon post, read them in your foreach loop with
$val = $_POST["textinput_{$trackid}"];
I am using following code to insert entry in my database. But i can add same entry multiple time and i wanna that whenever i submit same entry in input type then message will show "Nickname already exists "
<div>
<form>
<div>name <input type="text" name="na"/></div>
<div>marks1 <input type="text" name="m1"/></div>
<div>marks2<input type="text" name="m2"/></div>
<div>marks3 <input type="text" name="m3"/></div>
<div> <input type="submit" name="save" value="save"/></div>
</form>
</div>
And Here is my php code:-
<?php
if(!empty($_GET['save'])){
$na=$_GET['na'];
$m1=$_GET['m1'];
$m2=$_GET['m2'];
$m3=$_GET['m3'];
$query="insert into student(name,marks1,marks2,marks3) values('$na','$m1','$m2','$m3')";
mysqli_query($connect,$query);
}
?>
Make a unique column in database for example unique name for every student. So when you enter new record first check it that either it is present in the database or not. If its there then you can show error to user
For example you can set a unique constraint like this
Do a select before inserting in your base to check if the username already exists.
For your input message showing that the username already exists you can use a hidden paragraph:<p id="informationText" hidden>This paragraph should be hidden.</p>
Then once your select request has returned that the tuple already exists do an ajax query to show up this paragraph: $('#informationText').removeAttr('hidden');
That's a simple way, there is other better way to do that you can do some research about JavaScript Form Validation
FIRST EDIT
Here is a code sample:
<?php
if( isset( $_GET['save'] ) ){
$na=$_GET['na'];
$m1=$_GET['m1'];
$m2=$_GET['m2'];
$m3=$_GET['m3'];
$query = "select * from student where name = ? ";
$result = mysqli_query( $connect,$query, array( &$na ) );
$row = mysqli_fetch_row( $result );
if (count($row) > 0) {
echo "<script>$('#informationText').text = "Username already exists";$('#informationText').removeAttr('hidden');</script>";
} else {
$query="insert into student(name,marks1,marks2,marks3) values('$na','$m1','$m2','$m3')";
mysqli_query($connect,$query);
}
}
?>
I am trying to pass on a row ID by user click on the specified row, onto another page. I have a table with ID and info column.
code below displays the wanted row ID and info
if ($info = $stmnt2->fetch()) {
echo '<p>Your Info:</p>';
do {
echo "$info[id] . $info[review] . <a href=edit.php?edit=$info[id]>edit</a></br> </br>" ; //The info id is contained in the $info['id']
} while ($info = $stmnt2->fetch());
} else {
echo "<p>No Info</p>";
}
I want the user to be able to click on any of the rows and the selected row to pass on its ID onto another page. How do I do this?
This is the code on the other page and I want the ID on which the user clicked to replace "$info[id]" in the sql query. This replaces the whole column and not the specified row.
if(isset($_POST['id'])){
$update=$_POST['id'];
$db->exec("UPDATE infos SET info = '$update' WHERE reviewid = '$info[id]'");
}
In the edit page I have an input which the user can write to replace the selcted row (from the ID that gets passed on)
<form action="edit.php" method="POST">
<input type="text" name="id" value="">
<input type="submit" value=" Update "/>
</form>
So I want the ID that was passed from the first page to be used to replace the info row with the user input from the edit page
Pass the ID to the URL to the next page, navigate to the next page, then use $id =$_GET['id'];
Your edit=$info['id'] part is right but you're using $_POST and $_POST['id'], on the next page. The GET global is needed and it's named edit, not id
if ($info = $stmnt2->fetch()) {
echo '<p>Your Info:</p>';
do {
echo "$info[id] . $info[review] . <a href=edit.php?edit=$info[id]>edit</a></br> </br>" ; //The info id is contained in the $info['id']
} while ($info = $stmnt2->fetch());
} else {
echo "<p>No Info</p>";
}
edit.php:
if(isset($_GET['edit'])){
$update = $_GET['edit'];
$db->exec("UPDATE infos SET info = '$update' WHERE reviewid = '$info[id]'");
}
Also for future expansion and learning, read into how to do prepared statements with bound parameters if you are going to be using queries with variables built in. You're prone to sql injection currently and it's good practice to learn the newer and safer methods.
you can get the parameter value by using $_REQUEST
$update = $_REQUEST['edit'] in edit.php file
when you use $_REQUEST method you can catch both $_GET and $_POST values.
I am facing problem deleting the correct files. I am displaying the list of files uploaded by the user sorted by the time of upload (last upload first). If there's a list of 3-4 files, no matter which file I click to delete, the first file in the list gets deleted, the file last uploaded that is. Here is my page displaying the files a particular user has uploaded.
<?php
$uid=$faculty_data['faculty_id']; //Assigns logged in id to a variable
$query="SELECT * FROM uploads ORDER BY datetime DESC"; //Sorts by date time
$result=mysql_query($query);
while($row=mysql_fetch_assoc($result))
{
if($uid==$row['faculty_id']) //Checks if the logged in id matches with id in DB
{
echo '<form action="delete.php" method="POST">';
echo "<strong>File: </strong>";
$url=$row['link'];
$new="http://tofsis.com/fileshare/".$url;
echo "<a href='$new'>$new</a><br/>";
echo "<strong>On: </strong>".$row['datetime'];
echo '<br><input type="submit" name="delete" class="btn btn" value="Delete File"/>';
echo '<hr>';
echo '</form>';
}
}
?>
And this is my delete page:
<?php
$uid=$faculty_data['faculty_id'];
$query="SELECT * FROM uploads ORDER BY datetime DESC";
$result=mysql_query($query);
if(isset($_POST['delete']))
{
while($row=mysql_fetch_assoc($result))
{
if($uid==$row['faculty_id'])
{
$url=$row['link'];
$new="http://tofsis.com/fileshare/".$url;
$query="DELETE FROM uploads WHERE link = '$url'";
$result=mysql_query($query);
unlink($url);
}
}
header('Location: my_uploads.php');
exit();
}
else {
echo '<script type="text/javascript">alert("Oops something went wrong!")</script>';
header('Location: my_uploads.php');
exit();
}
?>
Can anyone please tell me where I am going wrong so that I can get my problem fixed?
A couple of changes should be make:
<?php
$uid=$faculty_data['faculty_id']; //Assigns logged in id to a variable
$query="SELECT * FROM uploads ORDER BY datetime DESC"; //Sorts by date time
$result=mysql_query($query);
while($row=mysql_fetch_assoc($result))
{
if($uid==$row['faculty_id']) //Checks if the logged in id matches with id in DB
{
$file_id = $row['id'];
echo '<form action="delete.php" method="POST">';
echo "<strong>File: </strong>";
$url=$row['link'];
$new="http://tofsis.com/fileshare/".$url;
echo "<a href='$new'>$new</a><br/>";
echo "<input type='hidden' value='$url' id='file_path' name='file_path' />";
echo "<input type='hidden' value='$file_id' id='id_file' name='id_file' />"; // new line
echo "<strong>On: </strong>".$row['datetime'];
echo '<br><input type="submit" name="delete" class="btn btn" value="Delete File"/>';
echo '<hr>';
echo '</form>';
}
}
?>
On the delete page, this:
<?php
$file_id=$_POST['id_file'];
$file_path = $_POST['file_path'];
$query="DELETE FROM uploads WHERE id = $file_id";
$result=mysql_query($query);
unlink($file_path); //this should works on deleting the file
?>
That should do the trick ;)
Add another hidden input that stores the File ID and Get it in your delete script and use it
You create a separate POST form for each available file but none of this forms contain any information about what file they refer to. I guess that $_POST contains nothing but a delete key with Delete File as value.
In your delete page, you read data from a variable that does not exist:
$uid=$faculty_data['faculty_id']
... and then you retrieve all files from the database to compare their ID against $uid. I guess you are removing all rows when the ID is zero.
To do:
Enable full error reporting. That's something you need to fix before you go further; it's impossible to code without the aid of error messages. Here's a brief explanation.
Add a hidden field to the form with the corresponding ID.
Read form data from $_POST, not from an arbitrary variable.
Learn some basic SQL, such as the WHERE clause, so you can do something like:
DELETE FROM uploads
WHERE faculty_id=333
Learn about SQL injection. Use a library that provides prepared statements.
I'm making a website on which I have a set of data with checkbox. I need to delete multiple rows from database when I select multiple checkboxes. I don't know how to pass the id of the selected checkboxes to next page. Please help me.
Here is my code:
$select_qry="select * from data";
$result=mysql_query($select_qry);
$rows=mysql_num_rows($result);
if($rows>0)
{
?>
<form action="delete_submit.php" method="post">
<?php
for($i=0;$i<$rows;$i++)
{
$arr=mysql_fetch_assoc($result);
$id=$arr['id'];
$name=$arr['name'];
//echo $id;echo "<br>";echo $name;
?>
<input name="checkbox[]" type="checkbox" value="<?php echo $id;?>">
<?php
}
}
?>
How can I pass the selected checkboxes' id to the next page? Please help me.
Thanks
when form will be submitted then $_POST['checkbox'] will be set and contain the array of selected ids.
In your delete script
if(isset($_POST['checkbox']) && count($_POST['checkbox']) > 0){
$deleteIds = $_POST['checkbox']; // it will be an array
$sql = "DEFRE FROM tablename WHERE id in (".implode("," , $deleteIds).") ";
// run the query
}