Foreach as - and PDO fetch_obj : newbie questions

Hi all,

I have something like this:

foreach($utilizadordao->seleccionar($utilizador) as $row) {

echo ($row->USERNAME_UTILIZADOR);
echo ($row->PASSWORD_UTILIZADOR);

}

And I’m enable to see the database records. But…

But I know that my select will only return one record, always. So I believe that I don’t need this foreach, and I’m trying to put the results inside some form textfields, so I don’t want a list of records to appear…

I’ve tried this:

foreach($utilizadordao->seleccionar($utilizador) as $row) {

$user=$row->USERNAME_UTILIZADOR;
$pass=$row->PASSWORD_UTILIZADOR;

}

And then on the form:

<input type="text" name="txt_username" id="txt_username" maxlength="20" value="<?php echo ($user); ?>"/>

<input type="text" name="txt_password" id="txt_password" maxlength="20" value="<?php echo ($pass); ?>"/>

But again, I can only display my records when I’m using the foreach.
Isn’t there another way to display the fetch data (I’ve used fetch_obj), without the need of using a foreach function ?

Thanks,
Márcio

I’ve never thank you for this post, but I really want to thank you oddz for your valuable help, always.

Thanks you very much for your time on helping other in such a great manner.
Márcio

Replace the foreach

foreach($utilizadordao->seleccionar($utilizador) as $row) { 

With just

$row = $utilizadordao->seleccionar($utilizador);

Ok… and I will keep this anyway:
$user=$row->USERNAME_UTILIZADOR;
$pass=$row->PASSWORD_UTILIZADOR;

because this is the only way we have to access specific columns on our results fetch. (in this case, using the PDO FETCH_OBJ), right? :rolleyes:

UPDATE: or better yet, I can change the input fields values to: $row->PASSWORD_UTILIZADOR; for example, avoiding yet another variable… correct? :slight_smile:

UPDATE 2: No I can’t. I’m getting nothing on my text fields if I make this changes… hmm… And I have also change only that line and I get nothing on the textfields either. Maybe the problem lies somewhere else… :frowning:

UPDATE 3: Maybe the problem relies on the way the method seleccionar is done…

Here it is, just in case:

public function seleccionar(Utilizador $utilizador) {
		
try {
			
$stmt = $this->_dbh->prepare("SELECT * FROM UTILIZADOR WHERE ID_UTILIZADOR=?");

$stmt->bindParam(1, $_SESSION['id_utilizador'], PDO::PARAM_INT);
			
$stmt->execute();
			
$rows = $stmt->fetchAll(PDO::FETCH_OBJ);
			
return $rows;
			
 } catch (PDOException $ex) {
			
echo "Erro: " . $ex->getMessage();
 }
}

Thanks a lot,
Márcio

fetchAll() returns an array. You want the first(only) element in the array. Either just access the first element directly like $row[0] or use fetch() instead of fetchAll()

$row = $utilizadordao->seleccionar($utilizador)[0]; 

i thought it returned a anonymous object. Maybe it does, but that anonymous objects must go to an array. is that it?

I also thought that if I access the [0] index of a fetched result I will only see the first column and not all the columns of one specific database row.

I will try again and see if I understand a little bit more and, of course, I will educate myself: http://pt2.php.net/manual/en/pdostatement.fetchall.php

Thanks for your comments, I will post back if the above solutions don’t work.

Regards,
Márcio

Ok… If I try:

$row = $utilizadordao->seleccionar($utilizador)[0]; 

I get a sintax error. :frowning:

If I do, something like this:

$row = $utilizadordao->seleccionar($utilizador);
$user=$row[0]->USERNAME_UTILIZADOR;
$pass=$row[0]->PASSWORD_UTILIZADOR; 

I get no sintax error, however, I’m getting this:

Fatal error: Cannot use object of type stdClass as array in /home/alterar_utilizador.php on line 46

And the line 46 is exactly this one:

$user=$row[0]->USERNAME_UTILIZADOR;

It makes sense, because what the method seleccionar returns should be an anonymous object, (I’m using the FETCH_OBJ), hence, not accessible like we do with an array… ??

Any other suggestion that will allow me to access the values of that object, on this scenario, without using the foreach, since I don’t need it?

Thanks a lot once again,
Márcio

I have revised my code, clean some things, and I’ve now re-tried this, since the error was that the $row as an anonymous object, I’ve tried to access that anonymous object that have the database columns as properties, like this:

$row=$utilizadordao->seleccionar($utilizador);
$user=$row->USERNAME_UTILIZADOR;
$pass=$row->PASSWORD_UTILIZADOR;

And it has worked. Weird, because, before I was getting only blank fields instead.

Thanks for your time on this,
Regards,
Márcio

I bet you changed the seleccionar() method :slight_smile:

I understand you have it working, but this doesn’t make sense because fetchAll returns a array not a object. Thus the variable $row should be a array with the domain objects. That is if you didn’t change the seleccionar() method.

Yes, i’ve change it. :blush: Didn’t realise that it was such a big change from FetchAll to Fetch. But I guess it is. Fetch all will always return as a array. Fetch not.

Let’s see if I get it:

Here is my new seleccionar method:


public function seleccionar(Utilizador $utilizador) {
		
	try {
			
		$stmt = $this->_dbh->prepare("SELECT * FROM UTILIZADOR WHERE ID_UTILIZADOR=?");
		$stmt->bindParam(1, $_SESSION['id_utilizador'], PDO::PARAM_INT);
		
		$stmt->execute();
			
		$row = $stmt->fetch(PDO::FETCH_OBJ);
			
		return $row;
			
		} catch (PDOException $ex) {
			
			echo "Erro: " . $ex->getMessage();
		}

Btw, I believe that instead of using a fetch with a style:

fetch(PDO::FETCH_OBJ)

we can actually do something like:

$row = $stmt->fetchObject();

anyway,

What i’d like to clarify is: when we are having this:

fetchAll(PDO::FETCH_OBJ) 

we are getting an ARRAY of anonymous OBJECTS ? Correct? And that’s why we can access the values by using a foreach or by accessing the index using .
So, having fetchAll this will work:

$resultado=$utilizadordao->seleccionar($utilizador);
$user=$resultado[0]->USERNAME_UTILIZADOR;
$pass=$resultado[0]->PASSWORD_UTILIZADOR;

Without the index reference of the array, or without using a foreach, it’s natural that we wouldn’t get values displayed, since we are not specifying where do we want to search for them.

Is this ok?

Thanks for your time,
Márcio

If the entity being returned is unique then you should generally return a single entity or null. Otherwise, yes a array would be appropriate.


// there can only be one user with a primary key of 2
$user = $userDAO->get(2);
$user->name;


// there can be several users with a status of 1
$users = $userDAO->get(array('status'=>1));
$users[0]->name;

Normally this is controlled with some type of argument in more generic systems or where you would like the level of control.


$user = $usersGateway->find('one',1);


$users = $usersGateway->find('all',array('status'=>1));

The argument should generally reference a class or interface constant though to make them flexible.


$user = $usersGateway->find(Gateway::findOne,1);


$users = $usersGateway->find(Gateway::findAll,array('status'=>1));

You could even use separate methods.


$user = $usersGateway->findOne(1);


$users = $usersGateway->findAll(array('status'=>1));

I prefer to use constants due to having a static find method. However, its probably best to use separate methods rather then constants.