Need input on a dynamic query output script - php

I have a homepage that has a bunch of images as links to other pages that has info about that image.
Image Name: $varExampleNAME
Damage: $varExampleDMG
Health: $varExampleHP
Mana: $varExampleMP
So the only info that will change on this page will be the variables.
What I want is to run one query script so that depending on the $fileName of the $currentPage
it grabs that row from the table if the $fileName matches a certain row name.
This is the script to find out what my fileName is:
//include database connection file
include_once 'connect_to_db.php';
$currentFile = $_SERVER["SCRIPT_NAME"];
$img = array_pop(explode("/", $currentFile));
$fileName$ = basename($img, ".php").PHP_EOL;
I'm having problems with the actual query script. Can anyone shed some light on how this will be done?
My table name is image_Name
Columns include id, name, damage, health, mana.

You should design your tables in order to fit your needs, in this case to retrieve a row based on a parameter.
If the name field of the table is consistent with the script filenames, you should do [using PDO]:
// Create a connection handler - provide your credentials
$dbh = new PDO('mysql:host=localhost;dbname=yourDbNane','username','password');
// Prepare the query with a placeholder
$dbh->prepare('SELECT * FROM image_Name WHERE name = ?');
// Fill the placeholder with the filename
$dbh->execute( array($fileName) );
// Fetch the result, you are done!
$img = $dbh->fetch();

Related

php, upload multiple files from multiple input

I have a form with multiple rows (rows from SQL, iterated and generated the form).
Each of those rows has a multiple file input field (the user can upload 0, 1 or multiple in each input).
Files are being uploaded correctly, with correctly assigned new file names (file names are generated based on each row SQL ID).
Then after user click the SUBMIT, the file names are added to a column in SQL table.
The form can generate 0, 1 ... 100 rows, so to prevent the php iterating through all those 100s rows, and executing an UPDATE or rows where it is not needed, I only execute the UPDATE on rows that the user has touched.
My problem is when I upload a single or multiple file on a singular file input field (a row), then everything works as expected.
However, when I try to upload 1 or more files in separate file inputs fields, then something strange happens in SQL, the files upload to the server are all OK, but database goes weird.
The first input (row) will have correct number of files with correct names, as desired.
Every next input (row, in the database after the UPDATE) will have the all the file names from all previous inputs, plus the ones that were uploaded for the specific input... if that makes sense... Here illustration:
Input 1: input1file1.jpg, input1file2.jpg
Input 2: input1file1.jpg, input1file2.jpg, input2file1.jpg
Because each input field can take multiple files, so the input name is already an array name='attachment[]'.
To distinguish between those input fields, I add row ID to file name.
Here is my code, I cannot work out what is causing it?
Form:
<form enctype="multipart/form-data" method="post">
...
php iteration:
<div>
<input class="hasChanged" name="attachments'.$row['pk'].'[]" type="file" multiple>
<input value="'.$row['existing_attachments'].'" id="updateAttachmentValue'.$row['pk'].'" name="existingAttachments'.$row['pk'].'">
</div>
...
</form>
PHP:
//iterate
foreach($_POST['foo_field'] as $key => $n){
if(in_array($upl[$key], $touched_rows)){
$aID = $upl[$key];
$prevAttachments = (empty($_POST['existingAttachments'.$aID]) || $_POST['existingAttachments'.$aID]=='|') ? NULL : $_POST['existingAttachments'.$aID];
$attachments = NULL;
if(count($_FILES['attachments'.$aID]['name']) > 0){
if(!empty($_FILES['attachments'.$aID])){
for($i=0; $i<count($_FILES['attachments'.$aID]['name']); $i++){//Loop through each file
$tmpFilePath = $_FILES['attachments'.$aID]['tmp_name'][$i];//Get the temp file path
if($tmpFilePath != ''){//Make sure we have a filepath
$shortname = 'AP-'.$aID.'-'.$_FILES['attachments'.$aID]['name'][$i];//save the filename
$filePath = $attachmentDirectory.'\AP-'.$aID.'-'.$_FILES['attachments'.$aID]['name'][$i];//save the url and the file
if(move_uploaded_file($tmpFilePath, $filePath)){//Upload the file into the correct dir
$files[] = $shortname;
}
$attachments = implode('|',$files);
}
}
}
}
$prevAttachments = !empty($attachments) ? $attachments.'|'.$prevAttachments : $prevAttachments;
try{
$stmt = $conn->prepare("EXEC [name].[dbo].[table] :p1,:p2");
$stmt->bindParam(':p1', $upl[$key], PDO::PARAM_INT);
$stmt->bindParam(':p2', $prevAttachments, PDO::PARAM_STR);
$stmt->execute();
}catch(PDOException $e){ echo 'ERROR: ' . $e->getMessage();}
}
}
In your code you never set or reset $files so that's why the value contains all previous files.
You should set $files = array(); at the beginning of each "row" to ensure $files only contains values for the specific row.

PHP - Check for distinct filename on file upload

I'm pretty new to PHP. I hate to have to ask questions, because I'm sure this is documented somewhere, but after looking for a while, I just cannot seem to put two and two together.
I have a program that will allow multiple images to be uploaded to an item within the database. Basically, for each item in the database, there might be multiple image uploads.
Example:
Item: Xbox 360
Images:
Xbox360.jpg
side.jpg
front.jpg
The image and item information is all stored in the database (MySQL), but the images are stored within the filesystem, and the database points to the URL of the image(s) in the filesystem.
The problem I'm having is that everything works as expected, except it allows duplicate image names to be written to the database. It doesn't allow duplicate images to be written to the filesystem, which I'm happy with. I want to make sure that the name of an image is only added once to the database. If the image name is a duplicate to another, it needs to not write to the database.
add_db.php:
$uniqueDir = uniqid();
$directory = "img/$uniqueDir/";
db_addItem($id_category, $name, $cost, $description, $qty, $directory); //Adds to the `items` table
foreach ($_FILES['i_file']['name'] as $filename) {
if ($filename != '' && $filename != 'No file chosen') {
//I think above is where I check for unique image names
$url = "img/$uniqueDir/$filename";
db_addImg($url, $filename); //Adds to the `img` table
$item_picsID = get_item_PicsID($filename, $url);
$itemID = get_itemID($directory);
db_insertImg($itemID, $item_picsID);
}
}
addFilesystem($directory); //Writes image(s) to filesystem
function db_addImg($url, $filename) {
include 'mysql_login_pdo.php';
// Create the SQL query
$query = "INSERT INTO img (`name`, `url`) VALUES(:filename, :url)";
$stmt = $db->prepare($query);
$stmt->execute(array(
':filename' => $filename,
':url' => $url
));
}
function db_insertImg($itemID, $item_picsID) {
include 'mysql_login_pdo.php';
// Create the SQL query
$query = "INSERT INTO `item_pics` (`item_id`, `img_id`) VALUES(:itemID, :item_picsID)";
$stmt = $db->prepare($query);
$stmt->execute(array(
':itemID' => $itemID,
':item_picsID' => $item_picsID
));
$db = null;
return;
}
Everything works, except it will write duplicate image names to the database. I want the image names to be distinct. I also don't want to rename the images (if possible).
You can define an UNIQUE index on the name column in img table, and then use slightly modified INSERT statement in your db_addImg function:
function db_addImg($url, $filename) {
//...
$query = "INSERT INGORE INTO img (`name`, `url`) VALUES(:filename, :url)";
//...
}
It will quietly cancel any insert where the is a UNIQUE key collision, which will end up in distinct filenames across your img table.
I would use a filename based on the primary key from the img table as you're guaranteed it's unique.
Otherwise, you'll need to guess a unique filename with some type of hashing and then check the file system. All of which can be expensive operations.
Looks like you are using PDO, so the static method lastInsertId will get the last insert id (primary key).
For example:
// after your insert to img
$filename = 'img' . $db->lastInsertId() . $extension;
This will require changing the img table slightly. But you're better off storing meta data (file type, size, etc) in this table as opposed to the file location (as that can change).
I think better to use hash value of your url as the primary key. Be cause string searching is much slower as int.

GET method for each table row having its own page

Say I have a database table titled "people" and under the column "names", I have "Bill", "Karen", and "Ted".
In my php file, I want to use just one template and using those rows, have a seperate page for each name (like "myfile.php?name=Bill"). From what I understand, I have to use GET, but I'm pretty still confused and inexperienced with that, so how would I go about obtaining my goal here?
If you want to make a page based of a name in the get variable use this.
This basicly takes the name and takes it to the database and selects all field pretaining to that name, then you echo out the varibles and place them where you want a such.
<?php
$name = $_GET["name"];//gets name value from your url that you supplied in your post
$con=mysqli_connect("127.0.0.1","db-username","db-pass","db-name");
mysqli_real_escape_string($con,$name);
$sql = mysqli_fetch_assoc(mysqli_query($con,"SELECT * FROM people WHERE names='$name'"));
$id = $sql['id'];//id would be a field in the people table
$age = $sql['age'];//age would be a field in the people table
echo '<h1>'.$name.'</h1>';
echo '<p>'. $id .'<br/>'. $ age .'</p>';
?>

if statment to check if something exists otherwise UPDATE

I have an .xml page that i want to pull data from every 6 hours.
this data is then inserted into the database and the unique Key is set as "characterID".
the code then need to check for the following an perfom an action based on its results.
If the .XML file contains characterID not already in database add the row!
If the database contains a characterID NOT in the .XML remove row!
If a row in the .XML file is different (THE CHARACTERID wont be different but other data will) to the row in the database UPDATE the row with new information WHERE charactedID is the same!
this is my current source code which loops through the XML and inserts the data correctly but i cannot update the information.
<?php
// INCLUDE DB CONNECTION FILE
include("includes/connect.php");
// CHANGE THE VALUES HERE
include("includes/config.php");
// URL FOR XML DATA
$url = "test.xml"; // For Testing Purposes
// RUN XML DATA READY FOR INSERT
$xml = simplexml_load_file($url);
// RUN SQL to check data already in table
$sql = mysql_query("SELECT * from `ecmt_memberlist`");
// Loop Through Names
foreach ($xml->result->rowset[0] as $value) {
$characterID = mysql_real_escape_string($value['characterID']);
$name = mysql_real_escape_string($value['name']);
$startDateTime = mysql_real_escape_string($value['startDateTime']);
$baseID = mysql_real_escape_string($value['baseID']);
$base = mysql_real_escape_string($value['base']);
$title = mysql_real_escape_string($value['title']);
$logonDateTime = mysql_real_escape_string($value['logonDateTime']);
$logoffDateTime = mysql_real_escape_string($value['logoffDateTime']);
$locationID = mysql_real_escape_string($value['locationID']);
$location = mysql_real_escape_string($value['location']);
$shipTypeID = mysql_real_escape_string($value['shipTypeID']);
$shipType = mysql_real_escape_string($value['shipType']);
$roles = mysql_real_escape_string($value['roles']);
$grantableRoles = mysql_real_escape_string($value['grantableRoles']);
// NOW LETS INSERT INTO DATABASE!!
$query = "INSERT INTO `ecmt_memberlist` SET
characterID='$characterID',
name='$name',
startDateTime='$startDateTime',
baseID='$baseID',
base='$base',
title='$title',
logonDateTime='$logonDateTime',
logoffDateTime='$logoffDateTime',
locationID='$locationID',
location='$location',
shipTypeID='$shipTypeID',
shipType='$shipType',
roles='$roles',
grantableRoles='$grantableRoles'";
//echo query to error check
echo $query;
echo "<br><br>";
mysql_query($query) or die(mysql_error());
};
?>
the table this gets inserted into will also hold some other information that will be associated with the characterID hence the need to "NOT REMOVE ROW AND REPLACE" else i will loose the associated data in that row when added manually.
You could first do a SELECT statement with the CharacterID. Than you can check if the rowcount is equal to 1. If this is the case you can update your row, otherwise you insert a new row in the database.

PHP check if variable exists in all rows returned

i want to do a check if a user id exists in all of the table rows i search for.
edit sorry i was missleading i think.
I want to check if the user has read all of the articles in a category, i have a forum front end displaying the categories and within the categories are the articles.
On the categories screen i want to display an image ALL ARTICLES READ or NOT ALL ARTICLES READ, so some how i need to loop through all of the articles per category which is what the example query below is doing and check if user id exists in ALL returned rows if yes then then all articles have been read if there are some rows missing the users id then some articles have not been read
This is my sql query
$colname_readposts = "-1";
if (isset($_GET['Thread_Category_Article_id'])) {
$colname_readposts = $_GET['Thread_Category_Article_id'];
}
mysql_select_db($database_test, $test);
$query_readposts = sprintf("SELECT Thread_Article_User_Read FROM Thread_Articles WHERE Thread_Category_Article_id = %s", GetSQLValueString($colname_readposts, "int"));
$readposts = mysql_query($query_readposts, $cutthroats) or die(mysql_error());
$row_readposts = mysql_fetch_assoc($readposts);
$totalRows_readposts = mysql_num_rows($readposts);
How can i check if all of the rows returned contain the users id?
The idea is to check to see if user has read all the articles if yes show READ if no show UNREAD.
The results per row are like so 0,15,20,37 these are id's entered when a user views a post.
i have managed to get this check for a single article to show if the user has read a specific article but unsure how i would check multiple:
here is my single article check:
<?php
$userid = $_SESSION['loggedin_id'];
$userreadlist = $row_readposts['Thread_Article_User_Read'];
$myarray = (explode(',',$userreadlist));
if (in_array($userid,$myarray )){
?>
html image READ
<?php } else { ?>
html image UNREAD
<?php } ?>
Any help would be appreciated.
Carl
First up, forget the mysql_* functions; ext/mysql is a deprecated API as of PHP 5.5 - so it's a really good idea to use mysqli or PDO.
From what I gather you're actually trying to see if any of those results contain a specific user's id? If so, do this in the SQL query:
SELECT Thread_Article_User_Read FROM Thread_Articles WHERE
Thread_Category_Article_id = %s AND UserID = %s
And supply this the User's ID as a second argument. (Syntax may not be 100% correct, but it should prove a point)
If you mean you want to check there there is any user's ID - then once again; do this in SQL:
SELECT Thread_Article_User_Read FROM Thread_Articles WHERE
Thread_Category_Article_id = %s AND UserID IS NOT NULL
This will ensure there is a valid value for 'UserID'.
Naturally replace 'UserID' with your column name if you base your solution on one of these examples.
However, if you're dumping out ALL the results from a table - and you need to see if your user's ID is present in a certain column (like you do!); then you can actually just adapt the logic that you're using on your single article page. Which should give you something like this...
$userid = $_SESSION['loggedin_id'];
$colname_readposts = "-1";
if (isset($_GET['Thread_Category_Article_id'])) {
$colname_readposts = $_GET['Thread_Category_Article_id'];
}
/* connect to db and run query; CHANGE ME TO SOMETHING NOT DEPRECATED */
mysql_select_db($database_test, $test);
$query_readposts =
sprintf("SELECT Thread_Article_User_Read FROM Thread_Articles WHERE
Thread_Category_Article_id = %s", GetSQLValueString($colname_readposts, "int"));
$readposts = mysql_query($query_readposts, $cutthroats) or die(mysql_error());
/* loop through all returned items */
while($row = mysql_fetch_assoc($readposts)) {
/* repeat the check you used on an individual
row on the single article page. i.e: */
$userreadlist = $row['Thread_Article_User_Read'];
$myarray = (explode(',',$userreadlist));
if (in_array($userid,$myarray )){
/* user has read */
} else {
/* user hasn't read */
}
}
If that code you worked for a single page then it should work in the above; as for every iteration of the loop you're working on a single row - just as you were on the single page. If the data is coming from the same table then the column names etc match up and it will work.
Or, if you just want to know if there are any unread posts at all, replace the loop with this one...
/* loop through all returned items */
$read = true;
while($row = mysql_fetch_assoc($readposts)) {
/* repeat the check you used on an individual
row on the single article page. i.e: */
$userreadlist = $row['Thread_Article_User_Read'];
$myarray = (explode(',',$userreadlist));
if (! in_array($userid,$myarray )){
$read = false;
break;
}
}
if( $read ){
/* all pages are read */
} else {
/* there are unread pages */
}

Categories