Artifact 14729dcef7bcf4475c3f69d3a064876c411ace33:
D 2015-02-26T19:23:28.809 L use\scases N text/x-markdown P ab353fe75fa49a38fed6fd557cbfbb2a72b980a1 U mario W 5907 <h2> Do's and Don'ts </h2> <div class=note> This isn't to discourage using phrep, but preemptively advise against a few unsuitable use cases. </div> * Don't overuse macros. They're neat, but can obstrue debugging once turned into lengthy substitution code. * Trivial code generation tasks are also provided by most IDEs. Unless you need customizations and iterative extensibility, just use basic code templates / copy + paste. * Phrep isn't meant as PHP/HTML templating engine. *Can't stress this enough*. While yes, you may simplify even Twig templates further; it's important to use the right tool for the job in the first place. * Same goes for localization. Preprocessor constants are even worse than in-application constants. Just use any gettext-style scheme. * While `#ifdef`, `#include` and friends can simplify project packaging and configurability, it's not always suitable for everyday web apps or genericized libraries. * Few projects need anything but classic/olden runtime configuration options (config.php, SQL table, ini, json, yaml) or in-code library setup (constructor params, plain props or constants). * Introducing a [make script](wiki/makefiles) for PHP projects *should* add significant advantages. Else you're just introducing a new dependency where historically there wasn't - and complicate its use for newcomers. * PHP, albeit less so than Ruby or Python, already provides heaps of dynamic runtime capabilities. For example variable variables are a core feature of PHP. And with some care even dynamic method or class creation are often an option. Don't use preprocessing just to eschew newbie-focused "Xyz is evil" and microoptimization memes. * Yet **feature branching** is actually **pretty simple** with *existing* tools. For example [`diff`](http://unixhelp.ed.ac.uk/CGI/man-cgi?diff) can not just create patches, but also inject macroprocessor `#ifdef` rules per <kbd>-D</kbd> flag: diff -D PKG_PREMIUM page.php page-extras.php > page.src That'll generate a source file suitable for `phrep` or any preprocessor. Oftentimes works for diffing multiple variants even. Which can be simpler than managing diversifying VCS branches for each variation. * And of course **code templating** is a practical <kbd>phrep</kbd> use case. * For example the slim [PARAMETERIZE@()](dir/examples/config) macro might be usable as-is for many database APIs. It allows to manage a terser table gateway collection. * Same goes for `HTML@()` whenever inline HTML shortcuts reduce code bloat. * Macros can also add extra readability to generated output. For example a simple `RX@()` handler that auto-comments regexps (e.g. via YAPE), or perhaps a `PSIX@()` wrapper compacting regexps to PCRE syntax. Foremost code templating can help with swapping out a concrete implementation without having to adapt source definitions. * Consuming C header `.h` files is an accidential by-feature of phrep. Albeit the use cases within PHP are pretty rare, since most system calls are abstracted away. * However `#include <errno.h>` could be used with `fsockopen`s $errno instead of plain boolean checks. * Or `#include <ext/mysqlnd/mysqlnd_priv.h>` bound for a few PDO error codes like `CR_OUT_OF_MEMORY`. But if it's just a few constants, copy+pasting them in or just codifying magic values remains preferrable to preprocessing. * Making authorization-related code paths preprocessor-dependant is a triple edged sword. - Most PHP frameworks tightly integrate authorization facilities already. And therefore should just be left to themselves. Adding conditional `#ifdef` sections to cement code paths and reduce runtime ambiguity is tempting, but in fact just adds another configurability layer. If code is made dependant on preprocessing before deployment, then at least always add fallback code: #ifdef AUTH_CLIENT_CERT $perm->default = SSLAuthPerm::from($_SERVER->list["SSL_*"]); #else ł(":auth", ":crit", "unconfigured", ":trace"); crash(); #endif Personally I'd be very wary of such uses. Getting the basics right isn't difficult nowadays, which is why most security woes arise from unobvious logic faults. → Complexity doesn't abet security. * The primary use case for preprocessing of course are packaging tasks. Phrep for instance works as library, or as CLI utility. To simplify distribution it's just merged into a single script then: #ifdef PKG_COMBINED #include <macro.php> #endif Which is why stripping PHP tags is an `#include` directive default. * A common use pattern for directives are conditional debug builds. Which can benefit PHP code just as well (in place of inline workarounds), such as: #ifdef USE_DEBUG #define DEBUG(x) print_r(x) #else #define DEBUG // #endif Using `DEBUG($var);` is somewhat more visual than literring plain `print_r` calls. (That regularily are forgotten about then). * Same goes for logging. It's quite uncommon for libraries to have any preparation for application level logging. If, it's at best an abstract interface which rarely gets utilized. With a plain `#define LOG(msg...)` binding to a concrete implementation it's heaps simpler, but doesn't complicate instantion when unneeded. * <kbd>phrep</kbd> itself also works for simple search and replace jobs like phrep -D strpos=stripos -i file.php -o=-i * Or even `#define mysql_query die`.<br> Just saying. Z d957b436833bc01445354b10ba99f877