A "filter" is just a function - the difference is just global state
indicating the current "default" function, which I think is a very bad
idea.

Just alias function calls as closures:

$html = function ($str) { return htmlspecialchars($str); }; // "default filter"
$attr = function ($str) { ... } // "attribute filter"

Then call them:

<?= $html($foo) ?>
<?= $attr($attr) ?>

IMO, this is much clearer and simpler (and more flexible) than hiding
a function name in global state.

Incidentally, that's what Aura HTML does: https://github.com/auraphp/Aura.Html

Rather than inventing a new concept (filters) why not leverage a
well-known quantity like functions? If they could autoload, that would
be a more explicit, natural and still pretty convenient way to
accomplish the same thing.

Hmm. Here's a thought.

You can already mix use-statements, right? I mean, you can "use"
either class/interface name or a namespace name.

At the time when PHP encounters the use-statement, it doesn't actually
decide what you imported, it just creates a file-wide alias for a
name.

That's why you can have a class and namespace with the same name and
"use" them both with one use-statement.

What if that worked for functions too?

    use MyNamespace\fun;

    fun(); // -> MyNamespace\fun()

This makes it convenient to import and call namespaced functions.

Okay, but to the real problem, autoloading functions... what if
spl_autoload_register() was triggered for missing functions as well as
for missing classes?

I know, I know - BC break, but think about it... with Composer there's
no problem? it'll just attempt to autoload "MyNamespace/fun.php" and
give up. If you were to follow that naming convention, it would
probably just work without any modifications at all.

What's funny is that spl_autoload_register() documentation page
doesn't in fact even say that it's for classes, hehehe ;-)

Okay, so I'm only half serious - It would probably be cleaner to add a
dedicated spl_autoload_func_register() or something?


On Mon, Jun 20, 2016 at 6:07 PM, Larry Garfield <la...@garfieldtech.com> wrote:
> On 06/20/2016 10:24 AM, Rasmus Schultz wrote:
>>>
>>> <ul>
>>> <?php foreach ( $things as $thing ) { ?>
>>> <li><a href="/things/<?= $thing['name'] ?>" onclick="show_popup('<?=
>>> $thing['name'] ?>');"><?= $thing['name'] ?></a>
>>> <?php } ?>
>>> </ul>
>>>
>>> There are three different escape mechanism needed there; if there is a
>>> shorthand for one, do you think it will be more likely or less that
>>> people
>>> will get the other two right?
>>
>> I have to agree with that - assigning special syntax to one kind of
>> escape-function gives that function an elevated status, which could
>> easily encourage neglect and oversight.
>>
>> I do wish that we had an obvious, consistently-named set of
>> web-related escape/encode functions for use in plain PHP templates,
>> like html(), attr(), js(), etc... having to type and read
>> htmlspecialchars() and json_encode() while you're trying to visually
>> parse a template is really inconvenient.
>>
>> That's all it is though, inconvenience. Nice to have, not must have.
>>
>> I'd be much more interested in a general solution to the problem of
>> being unable to (or at least strongly demotivated from) using actual
>> namespaced functions in this and many other cases - that's a missing
>> feature and a more general problem, whereas in my opinion an operator
>> or shorter function-names are just a work-around...
>>
>> (and please, nobody say "use a template engine" - I *am* using a
>> template engine, it's called PHP!)
>
>
> In many of the PHP template engines, there are multiple "filters" available
> with a specific syntax, and a way to add more.  You have to specify which
> one you want, because only you know the context.
>
> Twig (and possibly others?) lets you set a default escaper that can be
> overridden case by case as needed, including by a "none" option.
>
> Rather than try to make print statements themselves into a more secure
> template layer (Sorry, Rasmus, that ship has long since sailed, even Drupal
> gave up on PHPTemplate), perhaps it would be more useful to look at the
> needs of the various template engines (Twig, Smarty, Blade, etc.) and see
> what the language can/should do to make it easier for those engines to be
> made secure.  That same underlying tooling, then, can be exposed in a way
> that those still using PHP itself as a template engine can leverage it more
> easily.
>
> I'm not 100% certain what that would look like.  My initial thought (which
> is potentially a terrible idea), is some sort of callable registration, akin
> to stream wrappers or autoloaders, where you could do something vaguely like
> this:
>
> register_escaper('html', function($var) { return htmlentities($var,
> ENT_QUOTES | ENT_HTML5); });
> register_escaper('html_attrib', function($var) { ... });
> register_escaper('raw', function($var) { return $var;});
>
> set_default_escaper('html'); // I dislike a global flag like this, but it
> works for this demonstration.
>
> <?php
> print $foo; // no escaping, because BC.
> printe $foo; // Run through html escaper
> printe($foo, 'html_attrib'); // Run through html_attrib escaper
> ?>
>
> <?= $foo; ?> // No escaping
> <?~ $foo ?> // Run through html escaper
> <?~html_attrib $foo ?> // Run through html_attrib escaper
>
> And then Twig, Smarty, etc. can also leverage the registered escapers, and
> add their own as appropriate.
>
> That's off-the-cuff syntax that may be terrible, but the goal here is to
> better enable template engines (whether thick ones like Twig or thin ones
> like *.view.php) to do security better, rather than trying to Solve It For
> All The Things(tm), which for security is a very dangerous dead-end
> approach.
>
> --Larry Garfield
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to