how can i stop duplicate values from being shown? - php

Ok, so I Have been trying to figure this out for 2 days with no real success
This is the code I have
$splash_list = '';
$splash_array = array();
$sql = "SELECT * FROM pm WHERE receiver='$username' OR sender='$username'";
$query = mysqli_query($db, $sql);
while($row = mysqli_fetch_array($query, MYSQLI_ASSOC)){
if($username == $row['sender']){
$otuser = array_push($splash_array, $row['receiver']);
$this_user = $row['sender'];
} else {
$otuser = array_push($splash_array, $row['sender']);
$this_user = $row['receiver'];
}
}
foreach($splash_array as $otuser){
$splash_list .= '<div>'.$otuser.'<br></div>';
}
The output is
otuser1
otuser1
otuser1
otuser2
otuser2
If any one can give me a pointer on how i'd go about
only outputting each value once like so
otuser1
otuser2
It'd be greatly appreciated :)

Well you could do SELECT DISTINCT ... (DISTINCT optimization docs)
But there's some other serious concerns with your code...
SELECT * is evil
mysql_* functions are deprecated
Your code is vulnerable to SQL injections
Look into using PHP's PDO for more help.
Your resulting code will look something like
$query = $db->prepare("
SELECT DISTINCT sender, receiver
FROM pm
WHERE receiver = :username
or sender = :username
");
$result = $query->execute(array("username" => $username));
Notice the documentation suggests you should use a colon like this → ":username" => $username. A little known goodie about PDO parameter binding is that the : is optional. Youpi!

I think DISTINCT would not work for this. Because DISTINCT will return unique combinations of sender and reciever, so ('otuser1', 'otuser2') and ('otuser2', 'otuser1') would be different.
Easiest solution:
array array_unique ( array $array [, int $sort_flags = SORT_STRING ] )
http://de2.php.net/manual/en/function.array-unique.php

Related

making a foreach loop inside an SQL query or do it dynamically via PHP?

I have 2 tables in my DB, Polyptychs and Illustrations. The PK of Polyptychs is FK in Illustrations.
What I want to do is:
SELECT polyptychID FROM Polyptychs
and subsequently, foreach ID returned I need all illustrations.
Via PHP the solution is something like this(using PDO sintax):
<?php
//create the connection with DB
$sql = "SELECT polyptychID, polyptych_image FROM Polyptychs";
$stmt = $this->DBH->query($sql);
$resultTmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
$final_result = array();
foreach($resultTmp as $val){
$id = $val['polyptychID'];
$final_result["$id"]["image"] = $val['polyptych_image'];
$sql2 = "SELECT * FROM Illustrations WHERE polyptychID = :polyID";
$stmt2 = $this->DBH->prepare($sql2);
$stmt2->execute(array('polyID' => $id));
$resultTmp2 = $stmt2->fetchAll(PDO::FETCH_ASSOC);
$final_result["$id"]["illustrations"] = $resultTmp2;
unset($id);
unset($sql2);
unset($stmt2);
unset($resultTmp2);
}
?>
Now $final_result contains all polyptychID as key of the array and its relative image and illustrations (if there's no error in the code).
What I want to know is if there is an easier way to get it, maybe doing it via SQL, and what is the best solution.
Thanks
You could run just one query using Inner Join:
SELECT P.polyptychID, polyptych_image, I.*
FROM Polyptychs P
INNER JOIN Illustrations I ON I.polyptychID = p.polyptychID
Now you loop the results adding them to the same array structure polyptychID as keys and illustrations as an array:
<?php
$sql = "SELECT P.polyptychID, polyptych_image, I.*
FROM Polyptychs P
INNER JOIN Illustrations I ON I.polyptychID = p.polyptychID";
$stmt = $this->DBH->query($sql);
$resultTmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
$final_result = array();
foreach($resultTmp as $val){
$id = $val['polyptychID'];
$final_result["$id"]["image"] = $val['polyptych_image'];
// I'm not sure what's the ID for Illustration table, so I'll assume `illustrationID`
$final_result["$id"]["illustrations"][$val["illustrationID"]] = $val;
unset($id);
}
?>
Here's what I'd do, if I were you:
SELECT p.polyptychID as ID,
p.polyptych_image as image,
i.*
FROM Polyptychs p
INNER JOIN Illustrations i
ON i.polyptychID = p.polyptychID
In light of your comment, check this handy graph to understand why an INNER JOIN is what I chose to use here:
Then, to format the array in the way you want it, just write this:
$formatted = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$id = $row['ID'];
if (!isset($formatted[$id]))
{
$formatted[$id] = array(
'image' => $row['image'],
'illustrations' => array() //we'll set this in a minute
);
}
unset($row['ID'], $row['image']);//remove id & image values
$formatted[$id]['illustrations'][$row['illustrationsID']] = $row;//assign rest of result-set
}
Of course, if there are fields in the Illustrations called either ID or image, then you'd have to change the query to p.polyptychID AS p_ID or something. Just make sure the aliasses are unique and you'll be fine.
On the re-use of prepared statements, it seems to be something people tend to overlook, but you really can use the same prepared statements over and over. As luck would have it, in fact, I wrote an answer about this matter just this morning. I use some basic examples that might be applicable to your case, too. So if -for some reason- you can't do a join, you can simply write:
$stmt = $pdo->prepare(
'SELECT * FROM Illustrations WHERE polyptychID = :pId'
);
$baseStmt = $pdo->query(
'SELECT polyptychID, polyptych_image FROM Polyptychs'
);
$result = array()
while($row = $baseStmt->fetch(PDO::FETCH_ASSOC))
{
$result[$row['polyptychID']] = array(
'image' => $row['polyptych_image'],
'illustrations' => null
);
$stmt->execute( array(':pId' => $row['pId']));
$result[$row['polyptychID']]['illustrations'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
}

How to take value from array into integer (PHP)

Input :
$sql1 = "SELECT COUNT(*) FROM matchTrip where userTripId = :tripId";
$stmt1 = $this->db->prepare($sql1);
$stmt1->bindParam(':tripId', $trip, PDO::PARAM_INT);
$temp = $stmt1->fetchObject();
echo(json_encode($temp));
Output:
How to take value from array :
of which json_encode looks like this: {"COUNT(*)":"7"}
Any help will be appreciated.
Why don't you just give the column an alias in the SQL itself?
$sql1 = "SELECT COUNT(*) as myCount FROM matchTrip where userTripId = :tripId";
Makes the rest easier to work with.
Do you mean json_decode? You can just put it between quotes and it should work; $array["COUNT(*)"].
But you can also add "AS myCount" to your SQL.
if to get rid of all the useless stuff from your code
$sql = "SELECT COUNT(*) FROM matchTrip where userTripId = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute(array($table_of_user[$i]));
$count = $stmt->fetchColumn();
echo $count;
So why not just fecth as array?
$temp = $stmt1->fetch(PDO::FETCH_ASSOC);
echo $temp['COUNT(*)'];
Just use like this:
$json = json_encode($temp);
echo $json->{'COUNT(*)'}; // 7

PHP + convert array for use with IN statement

Lets say I want to send an email to the people who like big sized candy.
When I do this:
$query1 = mysql_query("SELECT id_candy FROM `candylist` WHERE
candysize > 100") or die(mysql_error());
$result = mysql_fetch_array( $query1 );
$query2 = mysql_query("SELECT mail FROM `buyers` WHERE
candysizeinterest IN ($result)
") or die(mysql_error());
This query2 is of course the issue.
$result is not in a proper format to be used and then I get the obvious error of:
**Unknown column 'Array' in 'where clause'**
I need help to format the results of the query in a way that it looks like:
($val1, $val2, $val3....and so on)
Then I will be able to use it for an IN statement.
But I just do not know how to do so.
Try
$array = array();
while($result = mysql_fetch_array( $query1 ))
{
$array[] = $result['id_candy'];
}
Then use implode
$in_condition = implode(',', $array);
At last
$query2 = mysql_query("SELECT mail FROM `buyers` WHERE candysizeinterest IN ($in_condition)
NOTE : please switch to PDO or mysqli_*
you have a mistake in your sintax of $query2 you place array instead of actual value
change
$query2 = mysql_query("SELECT mail FROM `buyers` WHERE candysizeinterest IN ($result)
to
$query2 = mysql_query("SELECT `mail` FROM `buyers` WHERE `candysizeinterest` IN ('".$result['id_candy']."')");
I would like to also to remember you that mysql_ functions are deprecated so i would advise you to switch to mysqli or PDO for new projects.
You can use implode() to turn your array into a comma separated string:
implode(',',$result);
You can use that with IN
To convery an array to a comma sepearted string you would use
implode (",",$array)

How to echo the result of count(*) AS in PHP?

I am using the count(*) AS, as an alternative to mysql_num_rows().
I get a count for all 3 kinds of feedback (positive, negative and neutral).
But I don't know how to assign the count of, say, positive feedback to a variable that I would call $positive_feedback and then, echo it. How can you do this with the following example?
I have this:
SELECT feedback, count(*) AS `count`
FROM feedback
WHERE seller='$user'
GROUP BY feedback
which gives something like that:
feedback | count
----------------
positive | 12
neutral | 8
negative | 3
$result = mysql_query($query); // with your query.
$feedback=array();
while ($row = mysql_fetch_assoc($result)) {
$feedback[$row['feedback']]=$row['count'];
}
It will give an array consisting of feedback['positive'],feedback['negative'] and so on with count stored in each.
Use Count(1), not Count(*), it's faster because the SQL engine can just use the count values from the counting B-Tree index and does not need to ever access any other values. If you plan to make this query a lot, make sure you add an index on the feedback tuple.
$query = "SELECT feedback, count(1) AS `count`...";
$result = mysql_query($query, $link); // don't forget to share your db conn
$feedbackArr = new array();
while ($row = mysql_fetch_assoc($result)) {
$feedbackArr[$row['feedback']] = (int)$row['count'];
}
echo "Positive Feedback: \n";
print_r($feedbackArr);
With PDO it will look something like this:
$dsn = "mysql:host=%;dbname=%"; // insert your host and dbname
$db = new PDO($dsn, $username, $password); // insert your username and pass
$sql = "
SELECT
feedback, count(*) AS `count`
FROM
feedback
WHERE
seller='$user'
GROUP BY feedback
";
$feedback = array();
foreach ( $db->query($sql) as $row ) {
$feedback[ $row['feedback'] ] = $row['count'];
}
// result in here
print_r ($feedback);

adding values into an array using a while loop

So what I'm trying to do is create a live friends search. To do this I need an array of names for AJAX to search through.
Heres my while loop.
if($_REQUEST['D'] == 'viewfriends') {
$FREINDS = array();
$FRIENDS_QUERY = "SELECT * FROM `FRIENDS` WHERE `USER` = '{$Modules['User']->Username}' AND `STATUS` = 'accepted' ORDER BY `ID` Limit 10 ;";
$FRIENDS_RESULT = mysql_query($FRIENDS_QUERY);
if(mysql_num_rows($FRIENDS_RESULT) > 0) {
while($FRIENDS_ROW = mysql_fetch_assoc($FRIENDS_RESULT)) {
$sql = "SELECT * FROM `USERS` WHERE `USERNAME` = '{$FRIENDS_ROW['FRIEND']}' ;";
$REQUEST_ROW = mysql_fetch_assoc(mysql_query($sql));
$FRIENDS = $REQUEST_ROW['USERNAME'];
}
echo json_encode($FRIENDS);
} else {
echo'<div class="update status">Sorry, You have no friends at this time. sadface.</div>';
}
}
I put the echo $FRIENDS in there as a test, right now it doesn't display anything. Where did I derp?
You can't echo an array. You can use either print_r($friends) to display the whole row of fields requested in the query (you request *)
or you can echo $friends['name'] (depending on how you declared name in your database)
try this:
if($_REQUEST['D'] == 'viewfriends') {
$FRIENDS = array();
$USERNAME = $Modules['User']->Username;
$SQL_QUERY = "SELECT F.*, U.* FROM FRIENDS AS F LEFT JOIN USER AS U ON F.USER = U.USERNAME WHERE F.USERNAME = '{$USERNAME}' AND STATUS = 'accepted' ORDER BY F.ID LIMIT 10";
$RESULTS = mysql_query($SQL_QUERY);
if(mysql_num_rows($RESULTS) > 0) {
while($ROW = mysql_fetch_assoc($RESULTS)) {
$FRIENDS[] = $ROW['USERNAME'];
}
echo json_encode($FRIENDS);
} else {
echo'<div class="update status">Sorry, You have no friends at this time. sadface.</div>';
}
}
$FRIENDS[] = $REQUEST_ROW['USERNAME'];
then print_r($FRIENDS); echo will output array you need to loop the array or echo json_encode($FRIENDS); to see something
also are you sure that USERNAME is uppercase and not just username in lowercase lowercase as well as for the table name.
also i think you can use a JOIN clause instead of making to SQL requests
You have syntax error:
$FREINDS = array(); should be $FRIENDS = array(); .
And also:
$FRIENDS = $REQUEST_ROW['USERNAME'] should be $FRIENDS[] = $REQUEST_ROW['USERNAME']
And
echo $FRIENDS; should be echo json_encode( $FRIENDS );
The PHP won't actually echo out an array. If you do an echo of an array, it outputs "Array". Plus your javascript wouldn't know what to do with a PHP array if it did pass it that way.
Try:
echo(json_encode($FRIENDS));
Also, you should really listen to the feedback in the comments. Your code is very vulnerable to attack and not set up to scale well for such a potentially huge app.
You have a couple of issues that make your code either less secure or less efficient. The most obvious inefficiency is that you are doing a database call inside your while loop, so if someone has 10 friends, that means you've done 11 database queries when you may have only needed one or two. Here are the two queries:
SELECT * FROM `FRIENDS`
WHERE `USER` = '{$Modules['User']->Username}'
AND `STATUS` = 'accepted' ORDER BY `ID` Limit 10
SELECT * FROM `USERS` WHERE `USERNAME` = '{$FRIENDS_ROW['FRIEND']}'
So before we determine if these two can be combined, the first big red flag is the SELECT *. I use it all of the time, but it will get you kicked out of the better database bars. In your case, it's really unnecessary. We know from the second query that the only thing you are using from the first query is the $FRIENDS_ROW['FRIEND'] to match against the USERNAME. So that first query can become:
SELECT FRIEND FROM `FRIENDS`
WHERE `USER` = '{$Modules['User']->Username}'
AND `STATUS` = 'accepted' ORDER BY `ID` Limit 10
You also have the SELECT * in the second query, and we can tell that (for now) the the only thing you are using is the USERNAME, so it can become:
SELECT USERNAME FROM `USERS` WHERE `USERNAME` = '{$FRIENDS_ROW['FRIEND']}'
Finally, we can see from the second query that the FRIEND name and the USERNAME are identical; otherwise why would you query for the usernames where the username equals the friend name. If that's the case, we can drop your second query completely, since we already know the usernames from the first query.
The reason why it's both inefficient and unsafe is because you are using the OG mysql functions, which are clunky and don't offer the option of prepared statements. Prepared statements let you (among other things) put variables in your query in such a way that when you actually call the query, the parts that are variables are known and can thus be sanitized, avoiding the horrors of mysql injections that everyone has mentioned.
I won't bore you with the play-by-play, but here is what your code might look like if you used the newer mysqli library with a prepared statement:
if($_REQUEST['D'] == 'viewfriends') {
$friends = array();
$friend_lookup = $mysqli->prepare("SELECT FRIEND FROM FRIENDS WHERE
USER = ? AND STATUS = 'accepted'
ORDER BY FRIEND");
$friend_lookup -> bind_param('s', $userName);
$userName = $Modules['User']->Username;
$friend_lookup -> execute();
$friend_lookup -> bind_result($friend);
while($friend_lookup -> fetch()) {
$friends[] = $friend;
}
if($friends) {
echo json_encode($friends);
} else {
echo "Sorry, no friends. Boo.";
}
}

Categories