Good afternoon all,
I'm in the finishing stages of making a website where users can register and login. After that they can upload documents such as .pdf and .docx and search for those documents. The users data gets stored in my users table which contains following:
idUsers int(11) PRIMARY KEY NOT NULL,
uidUsers TINYTEXT NOT NULL,
emailUsers TINYTEXT NOT NULL,
pwdUsers LONGTEXT NOT NULL,
Then I have a table called "files" where the files that are being uploaded by the user i stored. The table contains following:
id int(11) PRIMARY KEY NOT NULL,
usersId int(11) NOT NULL, - (Foreign key for idUsers in users table)
name varchar(255) NOT NULL,
title varchar(255) NOT NULL,
forfatter varchar(255) NOT NULL, (forfatter = author)
size int(11),
download int(11) (for later use)
So when a specific user are logged in and uploads document, the users "id" (primary key in users table) gets passed to "usersId" in my files table.
All of this is working perfectly fine so far.
Then the user are able to use a search function, where the user can search for name, title and author of the document, which also works fine.
I only need to make sure the user only can see the documents, that are being uploaded by themselves. But I can't figure it out. I've tried many different solutions so far.
I've tried a suggestion i saw, where i tried to make my mysqli_query look like this:
"
SELECT *
FROM files
WHERE id
AND usersId name LIKE '%$searchingq%'
OR title LIKE '%$searchingq%'
OR forfatter LIKE '%$searchingq%'
AND usersId='.$usersId.'"
That wasn't working out well. It felt like the sessions wasn't finding the id of the current $_SESSION.
My search .php looks like this:
$usersId = $_SESSION['userId'];
$output = '';
if (isset($_GET['search']) && $_GET['search'] !== ' ') {
$searchingq = $_GET['search'];
$q = mysqli_query($conn, "SELECT * FROM files WHERE `usersId` = {$usersId} AND (`name` LIKE '%{$searchingq}%' OR `title` LIKE '%{$searchingq}%' OR `forfatter` LIKE '%{$searchingq}% )");
$c = mysqli_num_rows($q);
if($c == 0) {
$output = '<p>No search results for: "' .$searchingq. '"</p>';
} else {
while($row = mysqli_fetch_array($q)) {
$name = $row['name'];
$title = $row['title'];
$forfatter = $row['forfatter'];
$download = $row['downloads'];
$output .=
Help is very appreciated!
When doing code like this, I like to first run the query itself just to get it right.
This type of filtering should be easy because you already have each file associated to a user.
The base query would be like this:
Assuming you are looking for files for user 99.
This is the basic query and is intended only to show how to get the files for a user. This does not go into the code.
SELECT * FROM files
WHERE `usersId` = 99
This would give you only files that belong to that user. Again, this is only to explain the query, not to go in the code.
Now let's add to the above query to include the search criteria. Assume we are looking for 'foo'
SELECT * FROM files
WHERE `usersId` = 99
AND (`name` LIKE '%foo%'
OR `title` LIKE '%foo%'
OR `forfatter` LIKE '%foo%' )
We now have a query we can use in code. Try this out by running it directly against your database.
This query says to find all the files for that user when any of the columns match the search criteria. You can, therefore, write this in PHP something like this:
(Some code has been removed for the sake of brevity)
$usersId = $_SESSION['userId']; // the user id of the logged in user.
// code removed
$searchingq = $_GET['search']; // the search string
$q = mysqli_query($conn, "
SELECT * FROM files
WHERE `usersId` = {$usersId}
AND (`name` LIKE '%{$searchingq}%'
OR `title` LIKE '%{$searchingq}%'
OR `forfatter` LIKE '%{$searchingq}% )";
while($row = mysqli_fetch_array($q)) {
// Do output here
}
The following is how to do it with prepared statements.
You can learn more about Prepared Statements here: https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
$stmt = $mysqli_prepare($conn, "
SELECT * FROM files
WHERE `usersId` = ?
AND (`name` LIKE '%?%'
OR `title` LIKE '%?%'
OR `forfatter` LIKE '%?% )");
// Replace the ?'s with the actual values.
mysqli_stmt_bind_param($stmt, "isss", $usersId, $searchingq, $searchingq, $searchingq);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_assoc($result)) {
// output goes here
}
Maybe you could try adding AND usersId=".$userId to the end of your query.
Related
I'm developing a news website with php-mysql.
This is the table:
news_id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
news_title VARCHAR(250) NOT NULL,
news_short_description TEXT NOT NULL,
news_full_content TEXT NOT NULL,
news_author VARCHAR(30) NOT NULL,
news_published_on DATE NOT NULL
)";
on the index page of the website will be shown the articles.
$sql = "SELECT news_id,news_title,news_short_description,news_full_content,news_author,news_published_on FROM ARTICOLI ORDER BY news_id DESC LIMIT 10";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<h3>". $row["news_title"]. " </h3><br> " . $row["news_short_description"]. "<br> " ."Posted by ". $row["news_author"]. "<br>";
}
} else {
echo "0 results";
}
WHAT I NEED?
i don't know how to create automatic pages and links for the single articles.
EXAMPLE: www.website.com/this-is-the-title-of-the-article.
i was thinking about using the id of the db table,but how to select one precise row?
can you help me? thanks!!! ;)
One idea.
First of all, you need to add a slug field in your table (https://en.wikipedia.org/wiki/Semantic_URL#Slug) which will hold the title in the form of this-is-the-title-of-the-article.
The assumption here would be that the "slug" will need to be a unique string in the table.
Secondly, you need to use some sort of rewrite mechanism (e.g. apache's mod_rewrite) to convert request of the form www.website.com/this-is-the-title-of-the-article to something you can handle via a PHP script.
For example www.website.com/this-is-the-title-of-the-article gets rewritten as as www.website.com/index.php?q=this-is-the-title-of-the-article).
Example .htaccess
RewriteRule ^(.*)$ /index.php?q=$1 [L]
index.php
<?php
$articleSlug = isset($_GET(["q"])?$_GET["q"]:null;
if ($articleSlug !== null) {
$query = "SELECT news_id,news_title,news_short_description,news_full_content,news_author,news_published_on FROM ARTICOLI WHERE slug=?"; // Bind the ? to $articleSlug
//Execute SQL here and echo the results
} else {
// 404 error
}
I understand this is a very vague description and this is only one way of doing it. I would personally suggest you look into an MVC framework like e.g. Laravel which has all of this functionality already built in.
I am using mysql to create a search function from a database, however from the way the rest of the program is designed the user must only return 1 result from the info they enter. That is fine for me to program errors and such but I am having trouble accepting multiple strings as inputs to select the data from the table?
How do I make people be able to enter a combination of multiple fields (firstname, phone) etc. and come up with the results that match them without having the empty fields skew the results? i.e(Phone number is blank so only returning people with blank phone numbers)?
SELECT * FROM `users` WHERE `First_Name` = '$_SESSION[queryfname]
At the moment above is what the query is and I am unsure of what function to use (AND, OR) any help would be appreciated. Thanks it advance.
Generally this is something you would handle in your programming language (seems to be PHP here), and only query for the fields you are provided. You could do that like so :
$wheres = array('1=1');
if($_SESSION['queryfname']){
$wheres[] = "`First_Name` = '{$_SESSION['queryfname']}'";
}
if($_SESSION['querypnumber']){
$wheres[] = "`Phone_Number` = '{$_SESSION['querypnumber']}'";
}
$sql = "
SELECT *
FROM `users`
WHERE " . implode($wheres,' AND ');
however if you are limited to doing it in your SQL, you could do something like this
SELECT
*
FROM `users`
WHERE
(
`First_Name` = '{$_SESSION['queryfname']}'
AND
`First_Name != ''
)
OR --Could also be AND
(
`Phone_Number` = '{$_SESSION['querypnumber']}'
AND
`Phone_Number` != ''
)
LIMIT 1
You can try the limit:
SELECT * FROM `users` WHERE `First_Name` = '$_SESSION[queryfname] LIMIT 1;
I am attempting to write a search algorithm, nothing too advanced but it isnt just WHERE field1 = 'searchtext'. I am trying to search all keywords across multiple fields.
I have done a bit of searching and it seems as though my take on the matter is not compliant with MySQL's use of 'IN' with other functions, however I cannot find anything that seems to suggest a better way either here on stackoverflow or using google on independant blogs and other tutorial sites.
$fields = array('type','suburb','postcode','address'); // Fields in db being searched
$queried = $db->real_escape_string($_REQUEST['keyword']); // Input from form
$keys = explode(" ",$queried); // Determine individual keywords
$sql = "SELECT * FROM `properties` WHERE "; // Beginning of SQL Statement
$frc = 0; // Field Counter
foreach($fields as $f){
$inner = ''; // Reset $inner each run
$irc = 0; // Reset Inner Counter each run
$frc++; // Increase Field Counter
if($frc != 1){ $sql .= " OR "; } // All except first runthrough
$sql .= "`".$f."` IN "; // `field` IN
foreach($keys as $k){
$irc++; // Increase inner counter
if($irc == 1){
$inner .= "('%".$k."%'"; // First Inner per run (aka each keyword)
}else{
$inner .= ", '%".$k."%'"; // All other Inners
}
}
$inner .= ")"; // Inner finishes run before reset
$sql .= $inner; // Add Inner to SQL ready for query
}
$sql .= ";"; // Clean finish to SQL statement
$SearchProperties = $db->query($sql); // Run Query
I have included commentary to help you understand my messy code and what I felt I was doing. The code is giving me the expected output, for example if I search the keyword "house" my output is as follows;
$queried = house 3064
$sql = SELECT * FROM `properties` WHERE `type` IN ('%house%', '%3064%') OR `suburb` IN ('%house%', '%3064%') OR `postcode` IN ('%house%', '%3064%') OR `address` IN ('%house%', '%3064%');
Within the type column there is house and townhouse, it should be able to hit both, and should hit anything with the postcode 3064 regardless of if it has house in another column (According to what I want to accomplish)
However after several hours of searching, although my output is as desired I don't believe it to be correct. Could anybody help shed some light on the CORRECT method of solving my quandry and WHY this does not work? I always like to understand and learn from these sort of misunderstandings.
Thank you for your help.
If you have wildcards, you want like rather than in:
SELECT *
FROM `properties`
WHERE (`type` LIKE '%house%') OR
(`suburb` LIKE '%house%') OR
(`postcode` LIKE '%house%') OR
(`address` LIKE '%house%');
However, I would strongly suggest that you investigate full text indexes (see here). The use of MATCH() may greatly simplify your efforts.
EDIT:
Your query is still incorrect. And you should still be using like:
SELECT *
FROM `properties`
WHERE (`type` LIKE '%house%' or type like '%3064%') OR
(`suburb` LIKE '%house%' or suburb like '%3064%') OR
(`postcode` LIKE '%house%' or postcode like '%3064%') OR
(`address` LIKE '%house%' or address like '%3064%');
Try change 'IN' to 'LIKE'.
For example
$queried = house
$sql = SELECT * FROM `properties` WHERE
`type` LIKE '%house%'
OR `suburb` LIKE '%house%'
OR `postcode` LIKE '%house%'
OR `address` LIKE '%house%';
If you have a several keywords, then you need change query.
For example
$queried = house 3064
$sql = SELECT * FROM `properties` WHERE
(`type` LIKE '%house%' AND `type` LIKE '%3064%')
OR (`suburb` LIKE '%house%' AND `suburb` LIKE '%3064%')
OR (`postcode` LIKE '%house%' AND `postcode` LIKE '%3064%')
OR (`address` LIKE '%house%' AND `address` LIKE '%3064%');
I'm building a simple bug tracking tool.
When you create a new project, all the info you fill in in the form, gets stored in the database.
When you create the new project you get redirected to a unique project page.
On top of the page it shows the name of the project, but it's not the name of the project I just created, it always shows the name of the first project in the MySQL table.
How can I show the name of the project I just created?
With this query I retrieve the data from the database.
$query = "SELECT CONCAT(name)
AS name FROM projects";
$result = #mysql_query ($query)
With this I show the project name, but it always shows the name of the first record in the table.
<?php
if ($row = mysql_fetch_array ($result))
echo '<h5>' . $row['name'] . '</h5>';
?>
It isn't yet SQL Injection prove and is far from complete... But I'm really struggling with this problem.
You need an AUTO_INCREMENT field on your table for a unique identifier (at least, you really should). Then you can do something like this:
<?php
$sql = new MySQLi('localhost', 'root', '', 'database');
$sql->query('INSERT INTO `projects` (`name`) VALUES ("Test Project");');
$projectID = $sql->insert_id; // Returns the auto_increment field value of the last insert query performed
// So this assumes you have a field in your table called "id" in this example
$res = $sql->query('SELECT CONCAT(`name`) AS `name` FROM `projects` WHERE `id` = '.$projectID.';');
if ($row = $res->fetch_assoc()) {
echo '<h5>'.$row['name'].'</h5>';
}
?>
Since you were calling for a redirect to the unique project page, you should have something like this: header("Location: project.php?id=$projectID");
Then, on project.php, you can attempt to fetch the project with the query above, only your query's WHERE clause should be something like:
'`id` = '.intval($_GET['id']).';'
Technically, you could pass all the project info along to the next page as a request or a session cookie and save yourself a query altogether. Just make sure you keep the id handy so it's easy to update the record.
Try using ORDER BY.
$query = "SELECT CONCAT(name)
AS name FROM projects ORDER BY id DESC";
This would show the most recent project (assuming you have an ID column).
However, a much better way is to have an ID variable on the page.
$query = "SELECT CONCAT(name)
AS name FROM projects WHERE id=?";
Hey guys sorry if this is an amateur question but I'm having a little trouble with this.
How do I display comments towards a specific page? (page.php?id=48)
Because right now, every time i post a comment, it displays on all pages instead of the one i wanted it to post on
Heres the code:
$userfinal=$_SESSION['username'];
$rs = mysql_query("SELECT id FROM searchengine") or die(mysql_error());
$rec = mysql_fetch_assoc($rs);
$id = $rec['id'];
// get the messages from the table.
$get_messages = mysql_query("SELECT messages_id FROM messages WHERE to_user='$id' ORDER BY messages_id DESC") or die(mysql_error());
$get_messages2 = mysql_query("SELECT * FROM messages WHERE to_user='$id' ORDER BY messages_id DESC") or die(mysql_error());
$num_messages = mysql_num_rows($get_messages);
// display each message title, with a link to their content
echo '<ul>';
for($count = 1; $count <= $num_messages; $count++){
$row = mysql_fetch_array($get_messages2);
// if the message is not read, show "(new)"
// after the title, else, just show the title.
if($row['message_read'] == 0)
Any help would be appreciated, thanks
take a look at my sample code.
Consider a table comments with the basic structure.
CREATE TABLE `comments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`comment` text NOT NULL,
`article_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
);
comment column will hold the text of your comment
article_id holds the foreign key of the article it belongs to.
now lets say you want to retrieve the comment from a particular articleid article.php?id=48
here is how you should be doing it.
$articleId = mysql_real_escape_string($_GET['id']);
$query = 'SELECT id,comment FROM comments WHERE article_id ='.$articleId;
$result = mysql_query($query);
while($row = mysql_fetch_array($result)) {
echo nl2br($row['comments']);
}
although my codes does not relate to your question at all, but it should give you the basic idea on how to implement the logic.
EDIT :
you should not use the code for production, the code is only meant to explain you to implement the logic, remember this code is vulnerable to SQL injections, if you want a temporary fix you could use mysql_real_escape_string() function to avoid it. check my updated code.
TIP : you should try and use PDO for all your database queries here is the tutorial to get you started http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/