This line is trying to concatenate your result object with a string:
if ($zoekt) {
$gryResultaten .= 'AND geslact_id = $zoekt';
}
which is probably why you’re getting the ‘non-object’ error (although I’m surprised PHP doesn’t complain about trying to concatenate an object and a string).
Try moving your SQL to a string, and modify it before performing the query, like this:
$sql = "SELECT P.profiel_id, P.gebruikersnaam, G.geslact_id
FROM profielen P
INNER JOIN profiel_geslacht PG ON P.profiel_id = PG.profiel_id
INNER JOIN geslacht G ON PG.geslacht_id = G.geslacht_id
WHERE isActive = '$isActive' ";
if ($zoekt) {
$sql .= 'AND geslact_id = $zoekt';
}
$gryResultaten = $pdo->query($sql);
// etc
Hi Fretburner. Thanks for your reply. This is all very confusing for me. I just switched to PDO. I used this sam kind of query before and it was working. Ok it was not true a form, but it returned results. I have no idea where to add the $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Should that be in my connection file? Again sorry for the ignorance, but I have no idea where to look at.
try
{
$pdo = new PDO('mysql:host=db_host;dbname=$db_name', $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
echo 'Er is een database fout opgetreden.';
exit();
}
$isActive = 1;
$zoekt = filter_input(INPUT_GET, 'zoekt', FILTER_SANITIZE_NUMBER_INT);
$sql = "SELECT P.profiel_id, P.gebruikersnaam, G.geslacht_id
FROM profielen P
INNER JOIN profiel_geslacht PG ON P.profiel_id = PG.profiel_id
INNER JOIN geslacht G ON PG.geslacht_id = G.geslacht_id
WHERE isActive = '$isActive' ";
if ($zoekt) {
$sql .= 'AND geslacht_id = $zoekt';
}
$gryResultaten = $pdo->query($sql);
while($row = $gryResultaten->fetch()) {
echo "<p>{$row['gebruikersnaam']}</p>";
}
So what should I adjust in this? Thanks again for your time and patience.
P.s. Concrats with the win of Brazil. Today I was in a bar in my town. The wife of the owner is Brazilian and they were giving away caipirinha’s. I loved them
Identify which table geslacht_id belongs to, P., G., PG.
if ($zoekt) {
$sql .= 'AND geslacht_id = $zoekt';
}
Also, probably not a big deal on INNER JOIN but you normally would list the Join table field first compared to one you are comparing it to.
So this would be backwards.
P.profiel_id = PG.profiel_id
This would be correct.
PG.profiel_id = P.profiel_id
Also, isActive should probably have a table identifer as in P.isActive
Hi Drummin. Thank you for all your input :tup: That works as a charm. Like I said in the opening post this was just a test query in the actual search form there are a few more fields involved i.e. leeftijd_van(age_from) and leeftijd_tot(age_to) so the query is now looking like this:
$isActive = 1;
$zoekt = filter_input(INPUT_GET, 'zoekt', FILTER_SANITIZE_NUMBER_INT);
$leeftijd_van = filter_input(INPUT_GET, 'leeftijd_van', FILTER_SANITIZE_STRING); // not sure if this should be a string
$leeftijd_tot = filter_input(INPUT_GET, 'leeftijd_tot', FILTER_SANITIZE_STRING); // not sure if this should be a string
$sql = "SELECT P.profiel_id,
P.gebruikersnaam,
P.dob,
EXTRACT(YEAR FROM (FROM_DAYS(DATEDIFF(NOW(),`dob`)))) AS age,
PG.geslacht_id
FROM profielen P
INNER
JOIN profiel_geslacht PG ON PG.profiel_id = P.profiel_id
INNER
JOIN geslacht G ON G.geslacht_id = PG.geslacht_id
WHERE P.isActive = $isActive ";
so following your previous code I added this to the PHP as well:
if ($leeftijd_van) {
$sql .= "AND age >= $leeftijd_van";
}
if ($leeftijd_tot) {
$sql .= "AND age <= $leeftijd_tot";
}
if ($leeftijd_van && $leeftijd_tot) {
$sql .= "AND age BETWEEN $leeftijd_van AND $leeftijd_tot";
}
if ($leeftijd_van){
$gryResultaten->bindParam(":leeftijd_van", $leeftijd_van);
}
if ($leeftijd_tot){
$gryResultaten->bindParam(":leeftijd_tot", $leeftijd_tot);
}
if ($leeftijd_van && $leeftijd_tot) {
$gryResultaten->bindParam(":leeftijd_van", $leeftijd_van);
$gryResultaten->bindParam(":leeftijd_tot", $leeftijd_tot);
}
But that is giving me errors again. I tried to sanitize the $leeftijd_van and $leeftijd_tot as NUMBER_INT as well. It doesn’t give a clear error just a Fatal error. What am I doing wrong with this?
Again thank you for the previous and thank you in advance.
It’s close but you need to use the placeholder names you are binding in the $sql. Also don’t forget that space between each one. I added the space before " AND…"
if ($leeftijd_van) {
$sql .= " AND age >= :leeftijd_van";
}
if ($leeftijd_tot) {
$sql .= " AND age <= :leeftijd_tot";
}
if ($leeftijd_van && $leeftijd_tot) {
$sql .= " AND age BETWEEN :leeftijd_van AND :leeftijd_tot";
}
if ($leeftijd_van){
$gryResultaten->bindParam(":leeftijd_van", $leeftijd_van);
}
if ($leeftijd_tot){
$gryResultaten->bindParam(":leeftijd_tot", $leeftijd_tot);
}
if ($leeftijd_van && $leeftijd_tot) {
$gryResultaten->bindParam(":leeftijd_van", $leeftijd_van);
$gryResultaten->bindParam(":leeftijd_tot", $leeftijd_tot);
}
I’m not all that sure about your IF statements. If you are going to use the Third BETWEEN IF statement I think it the fist two should also check that the “other one” is not set.
if (isset($leeftijd_van) && !isset($leeftijd_tot)) {
$sql .= " AND age >= :leeftijd_van";
}
if (isset($leeftijd_tot) && !isset($leeftijd_van)) {
$sql .= " AND age <= :leeftijd_tot";
}
if (isset($leeftijd_van) && isset($leeftijd_tot)) {
$sql .= " AND age BETWEEN :leeftijd_van AND :leeftijd_tot";
}
if (isset($leeftijd_van) && !isset($leeftijd_tot)){
$gryResultaten->bindParam(":leeftijd_van", $leeftijd_van);
}
if (isset($leeftijd_tot) && !isset($leeftijd_van)){
$gryResultaten->bindParam(":leeftijd_tot", $leeftijd_tot);
}
if (isset($leeftijd_van) && isset($leeftijd_tot)) {
$gryResultaten->bindParam(":leeftijd_van", $leeftijd_van);
$gryResultaten->bindParam(":leeftijd_tot", $leeftijd_tot);
}
However I don’t think you need the third one at all. The first two will handle the BETWEEN.
if ($leeftijd_van) {
$sql .= " AND age >= :leeftijd_van";
}
if ($leeftijd_tot) {
$sql .= " AND age <= :leeftijd_tot";
}
if ($leeftijd_van){
$gryResultaten->bindParam(":leeftijd_van", $leeftijd_van);
}
if ($leeftijd_tot){
$gryResultaten->bindParam(":leeftijd_tot", $leeftijd_tot);
}
Brilliant Drummin. I have learned a lot the last few days with the help of you and fretburner.
I am facing another problem though. When I tested your code I got an error that the column age could not be found. What is logic, since you can’t use a alias (age is created in the query i.e. EXTRACT(YEAR FROM (FROM_DAYS(DATEDIFF(NOW(),dob)))) AS age,) in a where clause . So first of all to make sure it was working I temporary added a field age to my table, and it was working as expected. After that I added a subquery to my query the following way:
$sql = "SELECT *
FROM (
P.profiel_id,
P.gebruikersnaam,
P.dob,
EXTRACT(YEAR FROM (FROM_DAYS(DATEDIFF(NOW(),`dob`)))) AS age,
PG.geslacht_id
FROM profielen P
INNER
JOIN profiel_geslacht PG ON PG.profiel_id = P.profiel_id
INNER
JOIN geslacht G ON G.geslacht_id = PG.geslacht_id
) AS SUB
WHERE P.isActive = :isActive ";
Which I expected would do the trick but it sn’t instead I get a fatal error i.e.
Fatal error: in C:\wamp\www\mysite\resultaten.php on line 75
What could be the reason? Thank you again in advance.
I have tried to take a different approach. Instead of using a subquery I used the DATEDIFF as I have it in the query itself in the AND clause as well, i.e.
$sql .= " AND EXTRACT(YEAR FROM (FROM_DAYS(DATEDIFF(NOW(),`dob`)))) AS age >= :leeftijd_van";
But still I get the fatal errorr. What should I adjust to make this work?
Thanks, although I’m not actually Brazilian, just a Brit far from home I might consider switching allegiance though if there were free caipirinhas on offer!
The problem with that query is I don’t think the syntax is correct for a sub-query… I think it has to be like this:
SELECT * FROM (SELECT x,y, z FROM c WHERE a = b) AS SUB …
Seeing as your main query is selecting all columns though, you don’t need a subquery. You could do:
SELECT P.profiel_id, P.gebruikersnaam, P.dob, EXTRACT(YEAR FROM (FROM_DAYS(DATEDIFF(NOW(),`dob`)))) AS age, PG.geslacht_id
FROM profielen P
INNER JOIN profiel_geslacht PG ON PG.profiel_id = P.profiel_id
INNER JOIN geslacht G ON G.geslacht_id = PG.geslacht_id
WHERE P.isActive = :isActive
I also think that there may be a problem with your age calculation, as my understanding is that FROM_DAYS expects the number of days since year 0 into a date, but you’re passing it the difference in days between two dates. The MySQL manual suggests calculating age like this:
$sql = "SELECT *
FROM ( P.profiel_id,
P.gebruikersnaam,
P.dob,
TIMESTAMPDIFF(YEAR,dob,CURDATE()) AS age,
PG.geslacht_id
FROM profielen P
INNER
JOIN profiel_geslacht PG ON PG.profiel_id = P.profiel_id
INNER
JOIN geslacht G ON G.geslacht_id = PG.geslacht_id
WHERE P.isActive = :isActive
) AS sub";
But still without the desired result. As you see did I also included the TIMESTAMPDIFF, but can’t see if it is working as I still got the fatal error
It looks like you’re still trying to do a subquery incorrectly. What you want is either this (note the addtional SELECT keyword within the subquery):
$sql = "SELECT *
FROM ( SELECT P.profiel_id,
P.gebruikersnaam,
P.dob,
TIMESTAMPDIFF(YEAR,dob,CURDATE()) AS age,
PG.geslacht_id
FROM profielen P
INNER
JOIN profiel_geslacht PG ON PG.profiel_id = P.profiel_id
INNER
JOIN geslacht G ON G.geslacht_id = PG.geslacht_id
WHERE P.isActive = :isActive
) AS sub";
or this (no subquery, even simpler):
$sql = "SELECT P.profiel_id,
P.gebruikersnaam,
P.dob,
TIMESTAMPDIFF(YEAR,dob,CURDATE()) AS age,
PG.geslacht_id
FROM profielen P
INNER
JOIN profiel_geslacht PG ON PG.profiel_id = P.profiel_id
INNER
JOIN geslacht G ON G.geslacht_id = PG.geslacht_id
WHERE P.isActive = :isActive";
Also, if you want to use a calculated column, such as age, within a WHERE clause then it’s probably simpler in this case just to repeat the calculation.
Hi fretburner. I just see my mistake! I forgot the select in the subquery. I have been starring at this way to long I guess. Sorry for the inconvinience. Now I have the query without subquery as you suggested and repeated the calculation in the where clause i.e.
$isActive = 1;
$zoekt = filter_input(INPUT_GET, 'zoekt', FILTER_SANITIZE_NUMBER_INT);
$leeftijd_van = filter_input(INPUT_GET, 'leeftijd_van', FILTER_SANITIZE_STRING);
$sql = "SELECT P.profiel_id,
P.gebruikersnaam,
P.dob,
TIMESTAMPDIFF(YEAR,dob,CURDATE()) AS age,
PG.geslacht_id
FROM profielen P
INNER
JOIN profiel_geslacht PG ON PG.profiel_id = P.profiel_id
INNER
JOIN geslacht G ON G.geslacht_id = PG.geslacht_id
WHERE P.isActive = :isActive";
if ($zoekt) {
$sql .= " AND PG.geslacht_id = :zoekt";
}
if ($leeftijd_van) {
$sql .= " AND TIMESTAMPDIFF(YEAR,dob,CURDATE()) AS age >= :leeftijd_van";
}
$gryResultaten = $pdo->prepare($sql);
$gryResultaten->bindParam(":isActive", $isActive);
if ($zoekt){
$gryResultaten->bindParam(":zoekt", $zoekt);
}
if ($leeftijd_van) {
$gryResultaten->bindParam(":leeftijd_van", $leeftijd_van);
}
$gryResultaten->execute();
while($row = $gryResultaten->fetch()) {
echo "<p>{$row['gebruikersnaam']}</p>";
}
But I still get an fatal error. I start loosing hair from pulling it