PHP回声似乎乱序发生

时间:2019-06-14 03:58:08

标签: php echo

我正在一个个人项目上,构建一些基本功能来处理PHP组件,以便可以用类似于React中的组件的方式来构建它们。我遇到了一些奇怪的行为,在这种情况下,如果我使用字符串插值内联渲染组件,则它会在代码中被调用的位置之前出现。通过将每个步骤作为自己的代码行运行,我能够使标记正确显示,但是我希望能够将这些组件包含在字符串中。为什么会发生这种乱序渲染?任何见识将不胜感激。

我试图返回包含的组件而不是回显它们,但是(也许因为使用了双引号?)它们根本不呈现。我还把这些组件串联在一起作为字符串。这是行不通的。如果我编写不同的代码行,并在每行之后以分号结尾,则可以得到预期的结果。

这就是我想要的工作:

    echo "
        <section class='videoInfo'>
            <h1>{$props[$video]->getProperty(VIDEO_PROP::TITLE)}</h1>
            <div class='secondary'>
                <span class='viewCount'>{$props[$video]->getProperty(VIDEO_PROP::VIEWS)} views</span>
                {$loader::render(COMPONENT::OPINION_CONTROLS)}
                {$loader::render(COMPONENT::VIDEO_DETAILS)}
            </div>
        </section>
    ";

我也尝试过这样做,这导致与上面相同的错误输出:

    echo "
        <section class='videoInfo'>
            <h1>{$props[$video]->getProperty(VIDEO_PROP::TITLE)}</h1>
            <div class='secondary'>
                <span class='viewCount'>{$props[$video]->getProperty(VIDEO_PROP::VIEWS)} views</span>" .
                $loader::render(COMPONENT::OPINION_CONTROLS) .
                $loader::render(COMPONENT::VIDEO_DETAILS) .
            "</div>
        </section>
    ";

这可以正常工作,但是编写起来比较麻烦:

    echo "
        <section class='videoInfo'>
            <h1>{$props[$video]->getProperty(VIDEO_PROP::TITLE)}</h1>
            <div class='secondary'>
                <span class='viewCount'>{$props[$video]->getProperty(VIDEO_PROP::VIEWS)} views</span>";
                $loader::render(COMPONENT::OPINION_CONTROLS);
                $loader::render(COMPONENT::VIDEO_DETAILS);
        echo "</div>
        </section>
    ";

我希望输出HTML能够反映出回显的字符串。因此,最终输出应如下所示:

<section class="videoInfo">
            <h1>Second Test</h1>
            <div class="secondary">
                <span class="viewCount">86 views</span>
        <!-- includes javascript for handling like/dislike buttons -->
        <script src="assets/js/opinions.js"></script>
        <div class="controls">

            <button class="opinion far fa-thumbs-up" onclick="like(this, 60)">
                <span class="text">0</span>
            </button>


            <button class="opinion far fa-thumbs-down" onclick="dislike(this, 60)">
                <span class="text">0</span>
            </button>

        </div>

        <!-- includes javascript for handling edit/subscribe buttons -->
        <script src="assets/js/videoInteractions.js"></script>
        <section class="details">
            <nav>

            <a href="profile.php?username=testman">
                <img src="assets/images/generic_profile.png" class="profilePic">
            </a>

            </nav>
            <div class="uploadInfo">
                <span class="uploader">
                    <a href="profile.php?username=testman">
                        testman
                    </a>
                </span>
                <span class="uploadDate">
                    Published on Jun 4, 2019
                </span>
            </div>

            <button class="subscribe " onclick="subscribe(&quot;chan123&quot;, &quot;testman&quot;, this)">
                <span class="text">Subscribe 0</span>
            </button>

            <section class="description">
                Testing view incrementing
            </section>
        </section>
    </div>
        </section>

这确实是我将每一步作为单独的代码行运行时得到的输出。但是,如果我使用字符串插值或串联,则组件加载顺序不正确。实际上,已加载的组件完全出现在videoInfo部分之前!



            <button class="opinion far fa-thumbs-up" onclick="like(this, 60)">
                <span class="text">0</span>
            </button>


            <button class="opinion far fa-thumbs-down" onclick="dislike(this, 60)">
                <span class="text">0</span>
            </button>


            <nav>

            <a href="profile.php?username=testman">
                <img src="assets/images/generic_profile.png" class="profilePic">
            </a>

            </nav>
            <div class="uploadInfo">
                <span class="uploader">
                    <a href="profile.php?username=testman">
                        testman
                    </a>
                </span>
                <span class="uploadDate">
                    Published on Jun 4, 2019
                </span>
            </div>

            <button class="subscribe " onclick="subscribe(&quot;chan123&quot;, &quot;testman&quot;, this)">
                <span class="text">Subscribe 0</span>
            </button>

            <section class="description">
                Testing view incrementing
            </section>

            <h1>Second Test</h1>
            <div class="secondary">
                <span class="viewCount">87 views</span>


            </div>

输出组件本身就是回显的字符串。他们看起来像这样:

(opinionControls)

    echo "
        <!-- includes javascript for handling like/dislike buttons -->
        <script src='assets/js/opinions.js'></script>
        <div class='controls'>
            $likeButton
            $dislikeButton
        </div>
    ";

(videoDetails)

    echo "
        <!-- includes javascript for handling edit/subscribe buttons -->
        <script src='assets/js/videoInteractions.js'></script>
        <section class='details'>
            <nav>
                $profileButton
            </nav>
            <div class='uploadInfo'>
                <span class='uploader'>
                    <a href='profile.php?username=$uploader'>
                        $uploader
                    </a>
                </span>
                <span class='uploadDate'>
                    Published on $formattedDate
                </span>
            </div>
            $interactButton
            <section class='description'>
                {$props[$video]->getProperty(VIDEO_PROP::DESCRIPTION)}
            </section>
        </section>
    ";

嵌套回声是否会从顶级回声中冒泡?我正在努力解决这种问题。

我试图通过使嵌套组件返回字符串而不是执行回声来调整嵌套组件,但是我没有运气让它们完全以这种方式呈现。我尝试在返回的字符串周围使用单引号和双引号。像这样:

    return '
        <!-- includes javascript for handling like/dislike buttons -->
        <script src=\'assets/js/opinions.js\'></script>
        <div class=\'controls\'>
            $likeButton
            $dislikeButton
        </div>
    ';

    return "
        <section class='videoInfo'>
            <h1>{$props[$video]->getProperty(VIDEO_PROP::TITLE)}</h1>
            <div class='secondary'>
                <span class='viewCount'>{$props[$video]->getProperty(VIDEO_PROP::VIEWS)} views</span>
                {$loader::render(COMPONENT::OPINION_CONTROLS)}
                {$loader::render(COMPONENT::VIDEO_DETAILS)}
            </div>
        </section>
    ";

$ loader :: render()函数非常简单。它调用一个函数,该函数在已在应用程序中较早填充的组件上调用include()。相关的ComponentLoader函数如下:

    // Load component into static primedComponents array as a key, with its value its props
    public static function primeComponentWithProps(string $includesPath, array $props)
    {
        self::$primedComponents[$includesPath] = $props;
    }
    // Extract component and props from static array, then include it on the page
    public static function render(string $includesPath)
    {
        $props = self::$primedComponents[$includesPath];
        $args = [$includesPath, $props];

        self::loadComponentWithProps(...$args);
        // remove the component from the array of primed components once it has been rendered
        unset(self::$primedComponents[$includesPath]);
    }

    /** used to import components that require props */
    public static function loadComponentWithProps(string $includesPath, array $props)
    {
        // extract($props);     // using extract() would allow props to be accessed directly by key names--but currently we are using a props array and accessing values by key to make it clearer what is going on in components which consume props
        include($includesPath);
    }

0 个答案:

没有答案