> the problem IS NOT that we don't have a solution.... > The problem IS that developer > must call these functions everywhere manually.
What you don't seem to get, is your proposal doesn't change that fact? It changes the syntax and means by which you select and call the function, but it still requires the same choice and the same due diligence - and thereby doesn't truly change anything. This new tag will not simply replace <?= $var ?> because you still need to output HTML sometimes. What you've coined "context" is really just a pseudo function-call - it does not automatically establish context, and if I have to specify the context, I'm really just specifying the function I'd like to call; specifying the right "context" requires the exact same choice and diligence as selecting the right function, all this does is wrap things in another layer of complexity and blur things out even more. At least, with a function call, I can tell which function is going to be called - rather than digging through an extra facility that takes, essentially, a function name, and calls it for me. In my view, this only complicates things - it somewhat changes the problem, but doesn't actually solve the problem... On Sat, Jul 30, 2016 at 8:06 AM, Michael Vostrikov < michael.vostri...@gmail.com> wrote: > > The aim in my mind would be to make escaping easier to do right, for > people who aren't already using a framework or templating engine with its > own solution. > > The current implementation doesn't seem to share these priorities; it > feels like a building block for framework developers, who probably have > their own solutions already. > > No! You don't understand what I'm trying to explain. This feature will be > useful for ALL applications without template engine - frameworks, CMS, > custom core. You say that frameworks have their own solutions already. But > the problem IS NOT that we don't have a solution. PHP already has built-in > function htmlspecialchars(), Yii has Html::escape(), Zend has > $this->escape(). This is not the problem. The problem IS that developer > must call these functions everywhere manually. > > <div> > <div data-user-id="<?= Html::escape($profile->user->id) ?>"> > <?= Html::escape($profile->name) ?> > </div> > <div> > <?= Html::escape($profile->description) ?> > </div> > <div> > <?= Html::escape($profile->age) ?> > </div> > <div> > <?= Html::escape($profile->position->name) ?> > </div> > <div> > <?= Html::escape($profile->group->name) ?> > </div> > <div> > <?= Html::escape($profile->organisation->address) ?> > </div> > </div> > > This is the same as calling constructor manually after every 'new' > statement: (new User)->__construct(...), (new Profile)->__construct(...). > We have special function '__construct', which is called automatically. I > suggest similar way for escaping. And because we cannot set the same magic > function name for all applications I suggest to do this by registering a > callable. > This is not intended for people who don't have escaping functions, this is > intended for people who already have escaping functions. RFC suggests the > way how to call these functions automatically. And people who don't have > escaping function may define it once, and it also will be called > automatically. > > > > > - you can define automatic escaping for a whole file or a block within a > file > > - there is an extra filter to skip the automatic escaping (not the same > as unescaping) > > - the above can be done with any "context", but the default is HTML > > - a "context" is not just the argument to a single all-powerful "escape" > function; you can register a new context by name, > without reimplementing > any of the existing functionality > > - other template functions can say that their output shouldn't be > escaped, or that their input should be pre-escaped > > - other functionality of the system is aware of these notions, and > designed to behave sensibly > > > I don't think there's any way PHP can ever reach that level of > sophistication, because most of the language knows nothing about "context"; > the feature we build in is only ever going to be a simple short-hand for > some basic function calls. > > Almost all of these points can be done with the system described in the > RFC. Application can allow or restrict new contexts (without reimplementing > any of the existing functionality). Any behavior can be defined in > userland, we just need a point of extension. > > <?php > class CsvTemplate > { > protected $escapers = []; > > > function render() > { > set_escape_handler([$this, 'escape']); > include $this->templateFile; > restore_escape_handler(); > } > > function escape($str, $context = 'csv') > { > switch ($context) { > case 'csv': > return $this->escapeCsv($str); > break; > > case 'raw': > return $str; > break; > > default: > if (isset($this->escapers[$context])) { > return call_user_func($this->escapers[$context], $str); > } > > throw new Exception('Unknown context'); > break; > } > } > > function setEscaper($context, $callable) > { > ... > } > } > ?> > > header1;header2; > <?* $data['field1'] ?>;<?* (int)$data['field2'], 'raw' ?>; > > > > > But secondly, because people are lazy, or misunderstand, or make mistakes > when they're in a hurry. Your RFC isn't going to magically fix all those > things. > > It exactly is going to fix all those things. If people will use this > operator with HTML escaping by default, standard <?= ?> operator will not > be needed. > > > > > Just a thought, but I can't help thinking that "improved escape > facilities and syntax" are a mere patch for a more than superficial > problem. > > The problem of differentiating HTML strings, which to not require > escaping, from other string, which do, could actually be viewed as a deeper > problem, which is the inability to tell string types apart. > > /** @var string product description as HTML, do not escape this */ > > public $description; > > This is another problem, and it depends on your infrastructure or business > logic. Only your application or model knows what is stored in > '$description'. What if I have a site for learning HTML and my > '$description' contains an example with HTML, which should be HTML-encoded > on the page with a lesson, so that it will look like source code? This is > not a task of escaping system. > > > > > And a more intelligent escape function, like: > > > > typedef HTML extends string; > > > > class ProductView > > { > > /** @var HTML product description */ > > public $description; > > } > > > > function html($str) { > > return $str instanceof HTML ? $str : htmlspecialchars($str); > > } > > You can do this now by defining class 'HTML' with '__toString' method, > without any typedefs. What is the problem? And anyway you must call your > 'html()' function everywhere, and this is the problem. >