0

In one shop the following function throws a fatal error. What does the error tell me exactly?

The function:

$product = wc_get_product( $product_id );
$price = $product->get_price();

The error:

Fatal error: 
Uncaught Error: Call to a member function get_price() on boolean in 

Does this mean that I get a boolean back instead of a string or number? The error is coming from the line where I invoke get_price()

Aleksandar
  • 1,496
  • 1
  • 18
  • 35
  • Why not just check? Either by using your IDEs debugger or by simply var dumping what you get back – JimL Sep 05 '17 at 11:44
  • @JimL Good question. This error is not happening on my test installation but on someone else's e-commerce shop. I don't have access to that installation. – Aleksandar Sep 05 '17 at 11:45
  • 2
    "_instead of a string or number_" instead of an *OBJECT* – Scuzzy Sep 05 '17 at 11:52
  • can you include a `var_dump` of `$product` in this question. – Reigel Gallarde Sep 05 '17 at 12:13
  • @Reigel I don't have access to the installation where the issue appears. In my test environment (any many shops that use this plugin code) no errors appear. – Aleksandar Sep 05 '17 at 12:27
  • then how can we solved this question now? – Reigel Gallarde Sep 05 '17 at 12:30
  • In which file you are using above code? Is this code under loop? Do you want just display the price in the listing? – Ravi gohil Sep 05 '17 at 12:34
  • @Reigel The answers of 'iquellis', 'Scuzzy' and 'RiggsFolly' helped me to replicate that issue. So basically I can confirm that get_price() should get an object but on the problematic shop installation it gets a boolean. I probably also understand why that is so and it is not an issue of my code. The question now remains if I should implement a check for the class (if not boolean then). But that would not solve the underlying issue of the shop using a non standard custom code which causes the problem. So I'm not sure what the best way is how the handle that fatal error. – Aleksandar Sep 05 '17 at 12:40
  • @alev In which file you are using above code? Is this code under loop? Do you want just display the price in the listing? – Ravi gohil Sep 05 '17 at 12:51
  • @Ravigohil It is a plugin. The problem is that this particular shop doesn't use the regular product pages where usually page ID = product ID. That is where my plugin has an issue. It relies on the fact that the page ID = product ID. Since that particular shop has some custom code that changes the page ID (and makes it non equal to product ID) there is no way for me to solve this, as my plugin is only designed for standard WooCommerce implementations. – Aleksandar Sep 05 '17 at 12:55
  • $product = new WC_Product( $post ); $product->get_price(); Try this one, hope it will work for you! – Ravi gohil Sep 05 '17 at 13:04
  • @alev above $post will your product id. – Ravi gohil Sep 05 '17 at 13:12

3 Answers3

7

Does this mean that I get a boolean back instead of a string or number?

Exactly. I assume that your $product_id does not exist and wc_get_product() returns false in that case. However, the documentation (https://docs.woocommerce.com/wc-apidocs/function-wc_get_product.html) says, the method would return null on non-existant products (if you are using WooCommerce).

And: A method call on a string or a number won't work as well. You are expecting an object in your code snippet.

Update

Take care for the other suggestions here as well.

If you are using methods with mixed return types (in this case bool/object), you should always check the response first, before using it as an object.

iquellis
  • 979
  • 1
  • 8
  • 26
  • That helps. Probably you are right. In that case that underlying e-commerce shop probably has some non standard implementation of it's product pages. – Aleksandar Sep 05 '17 at 11:57
  • The same thing happened to me: apparently the code tried to execute the function get_image() on a product that didn't exist anymore, after a re-import of products earlier. You could try and catch this empty/non-existent product to avoid this error. Just letting you know for those who are in the same situation. – kevin b. Oct 18 '21 at 09:28
5

One way to fix this is to check the class you expect before calling the expected function

$product = wc_get_product( $product_id )
if( $product instanceof WC_Product )
{
  $price = $product->get_price();
}

at which pointn you could add either futher logic or throw an error.

Scuzzy
  • 12,186
  • 1
  • 46
  • 46
  • Interesting. And what FOO would be? The product class? – Aleksandar Sep 05 '17 at 11:55
  • 2
    FOO (google for "foo bar") is just a placeholder. "instance of" is a PHP operator to check if a variable contains is an instance of a certain object. In your case $product instance of WC_Product would most likely the code that would fit your needs. – iquellis Sep 05 '17 at 12:09
  • Implementing your solution would avoid getting a fatal error. But then the shop owner wouldn't see that something is not as it should be (without the price my code is rendered almost useless). Would you advise to change my code in way that it at least throws a warning and adds a debug entry? Or wouldn't it be better to keep it as it is. In that case (like today) I would get an email of the shop owner and I could explain that the underlying issue is on his side. – Aleksandar Sep 05 '17 at 12:47
  • replace `FOO` with `WC_Product`. https://docs.woocommerce.com/wc-apidocs/function-wc_get_product.html returns either a instance of Class _WC_Product_ or _null_. see also http://php.net/manual/en/language.operators.type.php – Scuzzy Sep 05 '17 at 12:50
2

If $product is a boolean then this line

$product = wc_get_product( $product_id );

has failed !

You might start by checking what is in $product_id

RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
  • The error is coming from the line where I invoke get_price(). In that case, is you answer the same? – Aleksandar Sep 05 '17 at 11:46
  • 1
    Yes. If `wc_get_product( $product_id )` had succeded `$product` would be an object – RiggsFolly Sep 05 '17 at 11:47
  • That helps. Probably you are right. In that case that underlying e-commerce shop probably has some non standard implementation of it's product pages. – Aleksandar Sep 05 '17 at 11:57