tags:

views:

174

answers:

7
+1  Q: 

PHP: OOP issues

I am pretty new to OOP with PHP.

OK first of all this produces an error:

$mail->addBody(new MailWishListInquiry()->getBody(348));

but this doesn't:

$wishListInquiry = new MailWishListInquiry();
$mail->addBody($wishListInquiry->getBody(348));

I do not understand why?

Also the method getBody() is not returning anything..but no error either..here is a snippet of it:

function getBody($pid)
{

    $qry = 'SELECT * FROM cart_product WHERE product_id = '.$pid;
    $result = mysql_query($qry);
    $row = mysql_fetch_assoc($result);

    $item_name = $row['product_name'];
    $item_url = 'product.php?pid='.$pid;
    $item_image_url = 'product_images/'.$pid.'_sm_'.$row['product_image_sm'];

    return
    ?>
    <div style="width:600px; font-family:Arial, Helvetica, sans-serif; color:#333333;">

     ...

    </div>
    <?php
}

Does anyone know why?

Thanks!!

Edit: You guys have done a good job explaining that dereferencing doesnt work in PHP. But I still need help figuring out why getBody() is not returning a string. Is it because I am breaking out of the php so I don't have to quote it? Even if I pass nothing it should still return the html string right? Why is it not?

Thanks!

+10  A: 

I do not understand why?

Because PHP syntax arbitrarily says so: you cannot directly dereference (either as an object or as an array) return values from methods. You first need to assign them to variables.

Threre really is no meaningful semantical explanation behind this behaviour. As far as I know, this is furthermore subject to change in a future version of PHP.

Konrad Rudolph
True story, I would *LOVE* to see this changed in the future
Andrew G. Johnson
Thanks for that explanation! Do you know why getBody() is not returning anything?
John Isaacks
+1  A: 

PHP doesn't allow instant de-referencing. You can't do this either:

(new Something())->someMethod();
altCognito
+3  A: 

As for the first question, the other posters are correct. PHP doesn't let you directly dereference return values.

As for the second, your getBody() method will return null, which isn't an error (other than a logic error). As long as addBody() will accept a null parameter, your code will work.

As a side note and a matter of sanity, you should end the return in getBody() with a semicolon. There are such few instances in PHP where you don't need a semicolon at the end of a line that it can be confusing if you leave it out here, and cause errors in the future if the code is modified. The reason it still works is that the return statement is the last thing in the block.

In order to return the html instead of echoing it, you need it to be a string:

return '<div style="width:600px; font-family:Arial, Helvetica, sans-serif; color:#333333;">';
Brian Ramsay
I added semicolon, but I am passing it the int 348..and I am getting nothing returned. Is it because I am breaking the return string out of php and then breaking back into php? What can I do to fix it? Thanks!!
John Isaacks
Yes. Breaking out of php is essentially echo'ing your text rather than returning it. I edited my answer with a solution.
Brian Ramsay
A: 

As everyone has explained why you can't, i'll skip that part. But you can do this:

$mail->addBody(new MailWishListInquiry()->getBody(348));

can be

$mail->addBody( MailWishListInquiry::getBody(348));

i think. Try it out, should work.

Also, your getBody function isn't returning anything, and, everything after return isn't executed. (unless this has changed)

lyrae
@lyraeThat works only if getBody is a static method.
Tom
will work just fine its php remember
MrHus
http://us3.php.net/manual/en/language.oop5.basic.php see the examples it will work. Even though its crazy IMHO
MrHus
Thanks Tom. Forgot to mention that.
lyrae
+1  A: 

About get body, I've never seen a return returns things outside of php. But this could well be one of php quirks. But this should work:

<?php

function getBody($pid)
{

    $qry = 'SELECT * FROM cart_product WHERE product_id = '.$pid;
    $result = mysql_query($qry);
    $row = mysql_fetch_assoc($result);

    $item_name = $row['product_name'];
    $item_url = 'product.php?pid='.$pid;
    $item_image_url = 'product_images/'.$pid.'_sm_'.$row['product_image_sm'];

    return '<div style="width:600px; font-family:Arial, Helvetica, sans-serif; color:#333333;"></div>';

}

MrHus
Thanks, it works..so it was because I was breaking out of the PHP...strange...I have done that a lot without any problem before.
John Isaacks
+7  A: 

What others have said that you "cannot directly dereference return values from methods" is not quite correct. You actually 'just' cannot directly dereference newly created instances of a class, which is what you are trying to do. But it is of course possible to do somthing like this:

class Test {

public function a() {
 echo "a";
 return $this;
}

public function b() {
 echo "b";
 return $this;
}

public function c() {
 echo "c";
 return $this;
}

}

$test = new Test();

$test->a()->b()->c();

So you cannot directly do something with a newly created object, but you can do something with return values of methods.

Your other problem, that getBody does not return anything is because you are trying to return a block of HTML defined outside of the PHP block. You might think that PHP just takes everything you wrote between the ?> and <?php tags and return it as a string. But instead it will just write it to the standard output (usually your browser) and return from the method with no value (void).

To return a string of HTML, you can use normal string delimiters like this:

function getBody() {
    return
    '<p style="color: red;">Hello</p>
    <p>World</p>';
}
Simon Lehmann
Excellent answer!
John Isaacks
+1  A: 

If you want to return a string in that matter i recomend using obstart() and ob_get_contents

function getBody($pid)
{

    $qry = 'SELECT * FROM cart_product WHERE product_id = '.$pid;
    $result = mysql_query($qry);
    $row = mysql_fetch_assoc($result);

    $item_name = $row['product_name'];
    $item_url = 'product.php?pid='.$pid;
    $item_image_url = 'product_images/'.$pid.'_sm_'.$row['product_image_sm'];

    ob_start();
    ?>
    <div style="width:600px; font-family:Arial, Helvetica, sans-serif; color:#333333;">

        ...

    </div>
    <?php
    return ob_get_contents();
}
solomongaby