Skip to content
PHPue 0.0.3 · updated View as markdown

Common mistakes and verified fixes

Each row was compiled with PHPue 0.0.3's convert_pvue_file(). Many of these do not throw an error: the page silently renders the wrong thing. When something looks wrong, read the compiled PHP (?compile=views/page.pvue in dev, or convert_pvue_file() from the CLI).

Template output

You writeWhat happensFix
{{ $user.name }}PHP concatenation: wrong output and warnings{{ $user['name'] }} or {{ $user->name }}
{{ $tags }} (array)htmlspecialchars() TypeError{{ implode(', ', $tags) }}
{{ !$x }}, {{ (int)$x }}, {{ 'text' }}printed literally{{ $x ? '' : 'no' }}, {{ intval($x) }}, <?= ... ?>
{{ total() }} meant for Alpinecompiled as a PHP call: Call to undefined function total()x-text="total()"
class="x" {{ $on ? 'aria-current="page"' : '' }}quotes escaped: aria-current=&quot;page&quot;aria-current="{{ $on ? 'page' : 'false' }}" or <?= ... ?>
p-else, p-show, p-modelnot directives; left as dead attributesnegated p-if, raw PHP, value="{{ $x }}"
p-if element without its closing tagonly the opening tag is wrapped; content always rendersclose the element
p-for="item of $items"not converted (data-phpue-invalid-p-for)p-for="$item in $items"
Literal {{ $x }} in documentation textgets compiled&#123;&#123; $x &#125;&#125;

Blocks and files

You writeWhat happensFix
A closing script tag inside a PHP string or comment in <script>the PHP block ends there; the rest is dropped or a parse error'</scr' . 'ipt>'
const s = '<template>' in an inline <script> inside the templatecounted as a nested template; the template swallows the rest of the file'<tem' + 'plate>', or move the JS to <cscript>
JavaScript in <script> (Vue habit)PHP parse error: <script> is PHPbrowser JS goes in <cscript>
<html>, <head>, <body> in a .pvueduplicated document structurePHPue prints them; use <header> for head tags
Editing .pvue while .dist/ existsno effect; the compiled copy is serveddelete .dist/ or rebuild

Components

You writeWhat happensFix
<Card title="x"/>, <Card>slot</Card>not replaced: the raw tag is printed, nothing rendersset $cardTitle before <Card/>; components inherit scope
function helper() {} in a component used twice or in a loopCannot redeclare helper()move to backend/ or use a closure
const x = ... at the top level of a reused component's <cscript>JS Identifier 'x' has already been declaredIIFE, var, or move to the view/App cscript
<Card/> without @requirerenders nothing useful@require Card 'components/Card.pvue';
Component uses $title, parent also uses $titlethe component overwrites the parent's variablespecific names ($cardTitle)

Routing, scope and headers

You writeWhat happensFix
#require Home 'views/index.pvue';ignored (PHP # comment)#require 'views/index.pvue';
views/blog/post.pvue, URL /blog/post404flat views + query strings
?page=2 for paginationoverwritten by the route slug?p=2
App variable used in a viewundefinedbackend singleton, $_SESSION, define()
<title>{{ $postTitle }}</title> in a view headerprints the literal text $postTitledynamic meta from the App header (MetaControl)
{{ count($x) }} or {{ $a ?? '' }} in the App headernot convertedbuild the string in the App script, print {{ $titleTag }}
<?= $x ?> in the App headerprinted literally (it is a heredoc){{ $x }}
Inline <script>$(function(){...})</script> in the App header$ interpolated by the heredocmove JS to a file or <cscript>
phpue_set_lang('cy') in a viewtoo late, <html lang> already printedApp script or backend/
__DIR__ . '/data/x.json' in a viewbreaks after php index.php buildgetcwd() . '/data/x.json'
Variables named $routing, $current_route, $b404, $input, $actionreset by the compiled preambleother names

AJAX

You writeWhat happensFix
return ['ok' => true]; in a handlerempty responseecho json_encode(['ok' => true]);
fetch('', {method: 'POST', body: formData})no action found: the full HTML page comes back (200)send JSON, or a backend endpoint for uploads
Handler uses a variable set in the view scriptundefined (handlers run first)recompute in the handler or use a singleton
@AJAX('POST') called with GET (or the reverse)405match the method
Client calls a plain (non-@AJAX) function by actionfalls through to the HTML pagemark it @AJAX('POST')
Two handlers with the same name in different viewsfatal redeclareunique names app-wide

cscript

You writeWhat happensFix
const name = "{{ $name }}";""Ada"": JS syntax errorconst name = {{ $name }};
const n = {{ count($items) }};not converted: broken JSconst n = <?= json_encode(count($items)) ?>;

Sessions and caching

You writeWhat happensFix
Writing $_SESSION in a view with PHPUE_SESSION = 'lazy'lost for first-time visitors (no session yet)phpue_session(true) before the write
session_start() anywhere in the App script text (even a comment)PHPue's session handling switches offremove it; use phpue_session()
Expecting nginx/CDN caching with default settingsevery response sets a cookie and no-storePHPUE_SESSION = 'lazy'
A backend file that returns an array, loaded with require_oncesecond load returns true, not the arrayfolder with autoload.php, or require