webForumDet fria alternativet

PDO och while-loop som bara returnerar 1 post

8 svar · 1 586 visningar · startad av MickeA.com

MickeA.comMedlem sedan feb. 20034 528 inlägg
#1

Tjena,

Har en function som returnerar en array med bilder inkl. taggar, som ser ut såhär:

function GetImages($dbh = null, $Ids = ""){
	try {
		$query = "SELECT "
				."a.`imageId`, a.`imageParent`, a.`imageName`, a.`imageWidth`, a.`imageHeight`, a.`imageSize`, a.`imageCreated`, a.`imageCaption`, a.`imagePublished`, "
				."b.`tagId`, b.`tagX`, b.`tagY`, b.`tagBrand` " 
				."FROM images a "
				."INNER JOIN tags b "
				."ON a.imageId = b.tagParent "
				."WHERE a.imageId IN(:Images) "
				."ORDER BY a.imageId ASC, b.tagId ASC";

		$pst = $dbh->prepare($query);
		$pst->bindParam(":Images", $Ids, PDO::PARAM_STR);
		$pst->execute();
		
		$Imgs = array();
		while($res = $pst->fetch(PDO::FETCH_ASSOC)){

			$Imgs[$res['imageId']] = array(
					"id" => $res['imageId'],
					"name" => $res['imageName'],
					"width" => $res['imageWidth'],
					"height" => $res['imageHeight'],
					"caption" => $res['imageHeight'],
				);
			$Imgs[$res['imageId']]['tags'][] = array(
				"x" => (($res['tagX'] / $res['imageWidth']) * 100),
				"y" => (($res['tagY'] / $res['imageHeight']) * 100),
				"msg" => $res['tagBrand']
			);
		}
		return $Imgs;
		$res = null;
	} catch(PDOException $e){
		return $e->getMessage();
	}
}

Använder funktion såhär:

$Ids = implode(",", $_POST['imgId']);
	$Test = GetImages($dbh, $Ids);

Problemet är att array'en jag får tillbaka innehåller bara först raden i tabellen. Kör jag frågan separat direkt mot MySQL får jag 7 rader precis som det ska vara, men inte när jag kör funktionen.

Frågan ser ut såhär "utskriven":

SELECT 
a.`imageId`, a.`imageParent`, a.`imageName`, a.`imageWidth`, a.`imageHeight`, a.`imageSize`, a.`imageCreated`, a.`imageCaption`, a.`imagePublished`, 
b.`tagId`, b.`tagX`, b.`tagY`, b.`tagBrand` 
FROM images a 
INNER JOIN tags b 
ON a.imageId = b.tagParent 
WHERE a.imageId IN(13,7,4,5,2,3) 
ORDER BY a.imageId ASC, b.tagId ASC

Någon som har en hint vad det beror på? Har suttit och funderat och gjort om och funderat lite till men förstår inte vad som är på tok.

Tack!

danjelMedlem sedan juni 200444 inlägg
#2

du kan testa "array_push" annars..
misstänker att denna rad inte lägger till i arrayen
" $Imgs[$res['imageId']] = array( ..."

MickeA.comMedlem sedan feb. 20034 528 inlägg
#3

Nja, jag gör ju _alltid_ på det här viset, så det bör det inte vara...

När jag kör följande:

while($res = $pst->fetch(PDO::FETCH_ASSOC)){
   print_r($res);
}

Så skrivs också bara rad 1 ut, så det beror inte på det..

MickeA.comMedlem sedan feb. 20034 528 inlägg
#4

Nu har jag kommit på vad felet är, men har inte löst det...

$pst->bindParam(":Images", $Ids, PDO::PARAM_STR);

Jag skickar in värdet som 1,2,3,4,5 och verkar som om alla värden utom ett strippas bort av någon anledning... Testade att strunta i bindParam och skrev alla IDs manuellt i frågan och då fungerar det som det ska.

colioneMedlem sedan juni 20013 386 inlägg
#5

In frågor är lite komplicerade i prepared statements om jag minns rätt. Du får antingen bygga frågan dynamiskt eller lägga en while runt om dina idn typ:

$query = "SELECT " 
                ."a.`imageId`, a.`imageParent`, a.`imageName`, a.`imageWidth`, a.`imageHeight`, a.`imageSize`, a.`imageCreated`, a.`imageCaption`, a.`imagePublished`, " 
                ."b.`tagId`, b.`tagX`, b.`tagY`, b.`tagBrand` "  
                ."FROM images a " 
                ."INNER JOIN tags b " 
                ."ON a.imageId = b.tagParent " 
                ."WHERE a.imageId = :imageid" 
                ."ORDER BY a.imageId ASC, b.tagId ASC";
        $Imgs = array();  
        while($id = array_pop($Ids))){
                $pst->bindParam(":imageid", $id, PDO::PARAM_INT); 
                $pst->execute();
                if ($res = $pst->fetch(PDO::FETCH_ASSOC)) {
					$Imgs[$res['imageId']] = array( 
						"id" => $res['imageId'], 
						"name" => $res['imageName'], 
						"width" => $res['imageWidth'], 
						"height" => $res['imageHeight'], 
						"caption" => $res['imageHeight'], 
					); 
					$Imgs[$res['imageId']]['tags'][] = array( 
						"x" => (($res['tagX'] / $res['imageWidth']) * 100), 
						"y" => (($res['tagY'] / $res['imageHeight']) * 100), 
						"msg" => $res['tagBrand'] 
					); 
				}
		}
MickeA.comMedlem sedan feb. 20034 528 inlägg
#6

Hittade det här, ska kolla vidare på det imorrn...
http://stackoverflow.com/questions/920353/php-pdo-can-i-bind-an-array-to-an-in-condition

Återkommer!

MickeA.comMedlem sedan feb. 20034 528 inlägg
#7

Det fungerade bra att lösa det enligt länken ovan!

function GetImages($dbh = null, $Ids = array()){
	if(sizeof($Ids) == 0) return false;
	$Images = implode(",", array_fill(0, count($Ids), '?'));

	try {
		$query = "SELECT "
				."a.`imageId`, a.`imageParent`, a.`imageName`, a.`imageWidth`, a.`imageHeight`, a.`imageSize`, a.`imageCreated`, a.`imageCaption`, a.`imagePublished`, "
				."b.`tagId`, b.`tagX`, b.`tagY`, b.`tagBrand` " 
				."FROM images a "
				."INNER JOIN tags b "
				."ON a.imageId = b.tagParent "
				."WHERE a.imageId IN(" . $Images . ") "
				."ORDER BY a.imageId ASC, b.tagId ASC";

		$pst = $dbh->prepare($query);
		foreach ($Ids as $k => $id)
			$pst->bindValue(($k+1), $id);

		$pst->execute();
		
		$Imgs = array();
		$Curr = 0;
		$i = 0;

		while($res = $pst->fetch(PDO::FETCH_ASSOC)){
			...
		}
		return $Imgs;
		$res = null;
	} catch(PDOException $e){
		return $e->getMessage();
	}
}
MickeA.comMedlem sedan feb. 20034 528 inlägg
#8

Tja,

Nu har jag lite problem med något liknande problemet ovan. Jag behöver kombinera IN() och AND i en fråga och får inte till det alls.

Koden:

SELECT DISTINCT 
a.`tagId`, a.`tagName` 
FROM `tags` a 
INNER JOIN `user_tag` b 
ON a.`tagId` = b.`TagId` 
  INNER JOIN `user` c 
  ON b.`UserId` = c.`UserId` 
    INNER JOIN `answer` d 
    ON c.`UserId` = d.`AnswUser` 
WHERE d.`AnswQuestion` IN(?,?,?,?) 
AND d.`AnswSurvey` = ? 
ORDER BY a.`tagId`

Felmeddelandet:

pdostatement.execute: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

Såhär ser allt ut:

$Temp = array(
   1,
   2,
   3,
   4
);
$Questions = implode(",", array_fill(0, count($Temp), '?'));
$SurveyId = 123432543;

$query = "SELECT DISTINCT \n"
		."a.`tagId`, a.`tagName` \n"
		."FROM `tags` a \n"
		."INNER JOIN `user_tag` b \n"
		."ON a.`tagId` = b.`TagId` \n"
		."  INNER JOIN `user` c \n"
		."  ON b.`UserId` = c.`UserId` \n"
		."    INNER JOIN `answer` d \n"
		."    ON c.`UserId` = d.`AnswUser` \n"
		."WHERE d.`AnswQuestion` IN(" . $Questions . ") \n"
		."AND d.`AnswSurvey` = ? \n"
		."ORDER BY a.`tagId`";

$pst = $dbh->prepare($query);
foreach ($Temp as $k => $Id) $pst->bindValue(($k+1), $Id);
$pst->bindValue($k, $SurveyId, PDO::PARAM_INT);

$pst->execute();

Har testat t.ex. $k+1 osv. utan framgång.

Någon som har koll på en lösning på detta? Tack!

MickeA.comMedlem sedan feb. 20034 528 inlägg
#9

Gjorde ett snabbt test:

$Questions = array(
	"Keys" => array(
		":one",
		":two",
		":three"
	),
	"Values" => array(
		1,
		2,
		3
	)
);

$query = "SELECT DISTINCT \n"
		."a.`tagId`, a.`tagName` \n"
		."FROM `tags` a \n"
		."INNER JOIN `user_tag` b \n"
		."ON a.`tagId` = b.`TagId` \n"
		."  INNER JOIN `user` c \n"
		."  ON b.`UserId` = c.`UserId` \n"
		."    INNER JOIN `answer` d \n"
		."    ON c.`UserId` = d.`AnswUser` \n"
		."WHERE d.`AnswQuestion` IN(" . implode(",", $Questions['Keys']) . ") \n"
		."ORDER BY a.`tagName` ASC";
$Debug[]= $query;

$pst = $dbh->prepare($query);
foreach($Questions['Values'] as $Key => $Val) $pst->bindValue($Questions['Keys'][$Key], $Val, PDO::PARAM_INT);	
$pst->execute();

Det där fungerar utmärkt. Finns det några risker/problem/något dumt med det här sättet? Det enda problemet jag ser är ju att frågan inte kommer köras om de båda arrayerna är har olika storlek. Men det finns ju sätt att ta hand om det problemet också.

Genererad på 388 ms · cache AV · v20260730165559-full.f96bc7eb