tags:

views:

438

answers:

2

FINAL EDIT: I've summarized and simplified this crazy question into a new question, so we can close this Q or whatever is necessary to mark it resolved. Thanks again!

NEW:

Can you tell me your opinion of this, and possibly see if you can recreate it:

Currently, the $post->post_content variable contains:

"before <img src="/path/to/valid_img.gif" /> after"

This code placed at the top of the theme header.php...

------ Code --------
    1: $str = $post->post_content;
    2: assert( isset( $str ) );
    3: assert( is_string( $str ) );
    4: echo $str;
    5: $str = 'before <img src="/path/to/nonexistant.gif" /> after';
    6: assert( isset( $str ) );
    7: echo $str;
--------------------

Outputs this...

------ Output ------
before <img src="/path/to/valid_img.gif" /> after
before <img src="/path/to/nonexistant.gif" /> after
--------------------

With these warnings...

--- PHP Warnings ---
PHP Warning:  assert() [<a href='function.assert'>function.assert</a>]: Assertion
failed in /path/to/header.php on line 2
PHP Warning:  assert() [<a href='function.assert'>function.assert</a>]: Assertion
failed in /path/to/header.php on line 3
--------------------

Why would line 4 properly echo the $str if assert() fails twice when I KNOW 100% it should succeed?

What does a broken image src have to do with setting or unsetting the variable $str? WordPress bug/oddity?

Now the crazy part...

When lines 5-7 are commented out, thus eliminating the nonexistant.gif, the assert() warning does NOT appear and the output STILL properly produces this...

------ Output ------
before <img src="/path/to/valid_img.gif" /> after
--------------------

Any chance you can reproduce this and tell me what you think? I'm new to PHP, but I'm pretty sure this is crazyness. :)

OLD:

I'm relatively new to PHP and I have this code:

$str = $post->post_content; // hi -- [hw] -- bye <img src="foobar.png" />
$str = core_wp( 'foo_shortcode', $str );
echo $str; // return $str; produces the same warning message
// If there is no echo or return, the warning message is not produced.
// The warning disappears when I statically set (as object) the initial $str to
// "hi -- [hw] -- bye <img src="foobar.png" />".

When I run the above code, it works fine (foo-shortcode is doing it's job). The output is:

hi -- Hello World -- bye <img src="foobar.png" />

However I always get this warning message, telling me that foo-shortcode seems to be trying to run itself a second time, except the second time around, $str does not exist.

And the catch... I only get this warning message when $str contains an HTML img tag pointing to a non-existant src.

PHP Warning:  Missing argument 1 for foo_shortcode() in ...

And here is core-wp() and foo-shortcode():

function core_wp( $function, $a = NULL, $b = NULL )
{
    $wrap = array
    (
     'foo_shortcode'    => 'foo_shortcode',
    );
    $args = array();
    if ( isset( $a ) ) $args[] = $a;
    if ( isset( $b ) ) $args[] = $b;

    return call_user_func_array( $wrap[ $function ], $args );
}

function foo_shortcode( $content ) {
    return str_replace( '[hw]', 'Hello World', $content );
}

First, why would the code work fine, and then simultaneously seem to try to run itself a second time?

And regarding the $str containing an invalid img, I suspect this has something to do with the way WordPress generates $post->post_content.

EDIT 1 (Weds, July 22 @ 8:55am)

I added error-log() per your instructions like this:

error_log( 'done1' );
$str = $post->post_content;
error_log( 'done2' );
$str = core_wp( 'foo_shortcode', $str );
error_log( 'done3' );

... and it produced this in my error log:

[22-Jul-2009 08:52:49] done1
[22-Jul-2009 08:52:49] done2
[22-Jul-2009 08:52:49] PHP Warning:  Missing argument 1 for foo_shortcode() in
/home/path/to/header.php on line 23
[22-Jul-2009 08:52:49] done3

... and the output sent to the browser (correctly) was:

hi -- Hello World -- bye <img src="foobar.png" />

... but the warning message was still produced.

EDIT 2 (Weds, July 22 @ 9:18am)

I then tried this assertion:

59: $str = $post->post_content;
60: assert( isset( $str ) );
61: $str = core_wp( 'foo_shortcode', $str );
62: assert( isset( $str ) );

... and the PHP log shows:

[22-Jul-2009 09:16:55] PHP Warning:  assert() [<a 
href='function.assert'>function.assert</a>]: Assertion failed in
/home/path/to/header.php on line 60
[22-Jul-2009 09:16:55] PHP Warning:  Missing argument 1 for foo_shortcode() in
/home/path/to/header.php on line 23

... but again, the output is correct, yet the warning is still issued.

It seems to me that PHP is initially not setting $str = $post->post-content, then it runs core-wp( 'foo-shortcode', $str ) and says to itself "oh! I really need to set $str = $post->post-content..." goes back and sets it, and then outputs the correct data.

+1  A: 

I would try to initialize $args to array() just like you do with wrap. This shoud solve your issue.

function core_wp( $function, $a = NULL, $b = NULL )
{
  $wrap = array
  (
    'do_shortcode'                          => 'do_shortcode',
  );

  $args=array();
  if ( isset( $a ) ) $args[] = $a;
  if ( isset( $b ) ) $args[] = $b;

  return call_user_func_array( $wrap[ $function ], $args );
}

I can't say anything regarding the double execution: the code you post is not responsible for that.

Eineki
Nope, I tested and the problem is still there. Are you sure that $str = $post->post_content; evaluate to something different from Null?
Eineki
+1  A: 

If instead of

$str = $post->post_content;

You temporarilly put:

$str = 'some string you believe to trigger the error';

Does the error still occur? If so, that leads us to look at core_wp() for certain. If not, $post->post_content may be the culprit.

EDIT: To determine if $post->post_content is NULL, add the following lines:

echo "post_content:";
var_dump($post->post_content);
$str = $post->post_content;

Let us know if it's NULL when the error occurs.

EDIT2: Since you're sure $post->post_content is not NULL, try an error_log("done"); immediately after the code as you've posted it. Does the warning show up before or after "done"? Also, add error_log() statements to the top of all functions in question stating "called functionname" and that will help you determine if they're being called twice.

Josh
The culprit is most definitely $post->post_content because I tried exactly what you suggested -- I set a static $str containing the text which causes the warning and when I did, the warning went away. This is why I'm so confused. I don't know what to check next.
Jeff
That says to me that $post->post_content must be NULL
Josh
Hey Josh, since I'm new to PHP, can you explain how the $post-post_content could be NULL even though the proper results are returned? THAT is my main question.
Jeff
I'm not sure where $post->post_content is coming from... Let's start by determining if it is null. See my edited post
Josh
Hi Josh, that's exactly what I did -- in fact, I added var_dump($post->post_content) before AND after and it IS available. Thus, my conclusion that the function appears to be trying to run itself multiple times.
Jeff
What is the rest of the warning: "PHP Warning: Missing argument 1 for foo_shortcode() in ...". Should have a line number...
Josh
I'm probably abusing my editing privs but I added more to my answer. Please see the EDIT2: section
Josh
Missing argument 1 for foo_shortcode() in /home/path/to/header.php on line 25. This is the line that points to return str_replace( '[hw]', 'Hello World', $content );
Jeff
I truly appreciate the help. FYI, the warning message shows up in my PHP error log, not onscreen.
Jeff
OH! That's very helpful!
Josh
Try error_log() instead of echo. This will show you text in the error log, same as where the warning is, and should help you troubleshoot the flow leading up to the error.
Josh
Thanks Josh, I will try that and I also just learned about debug_print_backtrace() which I'll give a try a little later this morning.
Jeff
The debug_print_backtrace() was no help.
Jeff
@Jeff: Just read your edited post. Wow. What an odd scenario! Did you resolve this now or did you need further assistance?
Josh