<p>In craft 3 it is actually possible.</p>

<pre><code>{{ craft.app.view.evaluateDynamicContent('phpinfo();') }}
</code></pre>

<p>As you can see above, php code is passed as string to evaluateDynamicContent function. On inside, evaluateDynamicContent is just running <code>eval</code> function. </p>

<p>Now, even if you can do this, doesn't mean that you should. Before doing this, consider if you have other alternatives for doing what you want to achieve. Using php code inside template can run you into all kind of unpredicted security issues.</p>

CC BY-SA 4.0
2019-01-08T04:48:32.910Z
+1 because it's all true... but as piotrpog mentioned, _this is playing with fire and you should try hard to avoid it!_
Lindsey D
CC BY-SA 4.0
2019-01-08T01:44:31.327Z
2019-01-08T01:44:31.327Z
Piotr Pogorzelski
<p>I personally love separating querying and templating concerns and Craft's Twig implementation doesn't allow that very well. Writing queries inside templates doesn't sit well with me anymore after years in web development, so I went on to develop a small hidden plugin for Craft that allows a similar experience as Laravel's View Composers for Blade (hidden plugins start with an underscore character, they shouldn't, display in Craft's admin). In such, you can create a class that has the same name as your template to pass data to it before rendering. You can look it up here: <a href="https://github.com/guimauve-creative/craft-twig-view-composers" rel="nofollow noreferrer">https://github.com/guimauve-creative/craft-twig-view-composers</a></p>
<p>This allows to create PHP classes with a &quot;compose&quot; function where you can store some logic to abstract it from your view. It's not a controller per se because it runs at a higher level, when the request has already been treated, so that's why it's called a &quot;view composer&quot;.</p>
<pre class="lang-php prettyprint-override"><code>&lt;?php
/**
 * Basic view composer for the templates/index.twig file.
 * To create a view composer for a subfolder, simply replicate the structure here.
 * Ex.: templates/blog/_entry.twig -&gt; composers/blog/Entry.php
 *
 * Element queries are made with PHP to
 * avoid using their twig counterparts
 * @see https://craftcms.com/docs/4.x/element-queries.html
 */

namespace guimauve\composers;

use craft\events\TemplateEvent;
use craft\elements\Entry;
use Craft;

class Index
{

    /**
     * @param      TemplateEvent $event Object passed by View::EVENT_BEFORE_RENDER_TEMPLATE
     * @see        https://github.com/craftcms/cms/blob/a1b232ea1888f131bb7626a5bdaff0f5fa2f4469/src/web/View.php#L1891
     * @see        https://github.com/craftcms/cms/blob/2eac9249964ccc553bf841c79b9ee44d58f16b61/src/events/TemplateEvent.php
     *
     * @return     void
     */
    public static function compose(TemplateEvent $event)
    {
         $locations = Entry::find()-&gt;section('shop')-&gt;relatedTo($selectedCity)-&gt;with([
            [
                'featuredImage', ['withTransforms' =&gt; ['x870']]
            ]
        ])-&gt;collect();
        $event-&gt;variables['locations'] = $locations;
    }
}
</code></pre>
<p>In other words, what this plugin does, is basically just look inside a specific folder if there's a class that contains a file with the same name of the template that's being executed. For &quot;templates/blog/_entry.twig&quot;, it will look, load and execute a &quot;compose&quot; function on a PHP class if it's found at &quot;composer/blog/Entry.php&quot;.</p>
<p>The compose function receives the only variable that we had access to which is the TemplateEvent $event variable, but lucky for us, this variable contains all the data that craft has pre-parsed for the template and we can graft anything onto it through the &quot;variables&quot; array index. If I collect blog entries, for example, and add them to the $event-&gt;variables['blogs'] array index, it'll be available in my twig templates as &quot;blogs&quot;. Since all the database query functions we usually see in Twig are available in PHP too, we can use these counterparts and keep our code as clean as possible with better separation of concern.</p>
<p>Happy coding!</p>

CC BY-SA 4.0
2023-12-20T16:12:05.610Z
2023-12-20T19:34:45.293Z
2023-12-20T19:34:45.293Z
davidwebca
<p>No this is not possible.</p>

<p>If you really need PHP, you can write a plugin with one of the following:</p>

<ul>
<li>a <strong><a href="http://buildwithcraft.com/docs/plugins/variables">Template Variable</a></strong> class, which can be accessed from your templates via <code>craft.myPluginHandle</code></li>
<li>a <strong><a href="http://twig.sensiolabs.org/doc/advanced.html#creating-an-extension">Twig extension</a></strong>, which can add its own global <a href="http://twig.sensiolabs.org/doc/advanced.html#filters">filters</a>, <a href="http://twig.sensiolabs.org/doc/advanced.html#functions">functions</a>, or <a href="http://twig.sensiolabs.org/doc/advanced.html#tags">tags</a>, etc.</li>
<li>a <strong><a href="http://buildwithcraft.com/docs/plugins/controllers">controller</a></strong>, which can execute PHP before calling <code>$this-&gt;renderTemplate(...)</code></li>
<li>a <strong><a href="http://buildwithcraft.com/classreference/services/TemplatesService#hook-detail">template hook</a></strong>, which allows PHP code to access and modify the current template variable context, wherever the <code>{% hook %}</code> tag is placed.</li>
</ul>

<p><strong>Why Twig anyway?</strong></p>

<p>The question to use php in templates comes up every once in a while, but there are good reasons for not using it.</p>

<p>For example if Craft changes its code you don't have to worry about your templates. The upcoming update of the <a href="http://www.yiiframework.com/doc-2.0/guide-upgrade-from-v1.html">Yii framework</a> would force you to rewrite all your templates if they were written in php.</p>

<p>There is also a great <a href="http://fabien.potencier.org/article/34/templating-engines-in-php">article from Fabien Potencier</a> on this topic -- <em>tl;dr</em> php is too verbose for templating.</p>

CC BY-SA 3.0
2014-07-03T17:15:13.253Z
Thanks Brad, I didn't even knew there were template hooks.
Victor
CC BY-SA 3.0
2014-07-03T17:17:07.637Z
Little known, but very handy feature!
Brad Bell
CC BY-SA 3.0
2014-07-03T16:49:22.190Z
2014-09-09T16:11:18.053Z
2014-09-09T16:11:18.053Z
Victor
<p>Is it possible to use strait PHP in our templates along side of Twig and or instead of Twig?</p>

<p>If so how does one go about it?</p>

<templating><php>
Can we use PHP in our templates instead of Twig?
# Can we use PHP in our templates instead of Twig?

(Asked by: username_0 on 2014-07-03)

Is it possible to use strait PHP in our templates along side of Twig and or instead of Twig?

If so how does one go about it?

**Tags:** templating, php


---

## 3 answers

### Answer by username_4 on 2014-07-03. Score: 25 | Accepted answer

No this is not possible.

If you really need PHP, you can write a plugin with one of the following:

* a **[Template Variable](http://buildwithcraft.com/docs/plugins/variables)** class, which can be accessed from your templates via `craft.myPluginHandle`
* a **[Twig extension](http://twig.sensiolabs.org/doc/advanced.html#creating-an-extension)**, which can add its own global [filters](http://twig.sensiolabs.org/doc/advanced.html#filters), [functions](http://twig.sensiolabs.org/doc/advanced.html#functions), or [tags](http://twig.sensiolabs.org/doc/advanced.html#tags), etc.
* a **[controller](http://buildwithcraft.com/docs/plugins/controllers)**, which can execute PHP before calling `$this->renderTemplate(...)`
* a **[template hook](http://buildwithcraft.com/classreference/services/TemplatesService#hook-detail)**, which allows PHP code to access and modify the current template variable context, wherever the `{% hook %}` tag is placed.

**Why Twig anyway?**

The question to use php in templates comes up every once in a while, but there are good reasons for not using it.

For example if Craft changes its code you don't have to worry about your templates. The upcoming update of the [Yii framework](http://www.yiiframework.com/doc-2.0/guide-upgrade-from-v1.html) would force you to rewrite all your templates if they were written in php.

There is also a great [article from Fabien Potencier](http://fabien.potencier.org/article/34/templating-engines-in-php) on this topic -- *tl;dr* php is too verbose for templating.

> **Comments:**
> **username_4**: Thanks Brad, I didn't even knew there were template hooks.  
> **username_5**: Little known, but very handy feature!  

---

### Answer by username_1 on 2019-01-08. Score: 4

In craft 3 it is actually possible.
{{ craft.app.view.evaluateDynamicContent('phpinfo();') }}

As you can see above, php code is passed as string to evaluateDynamicContent function. On inside, evaluateDynamicContent is just running eval function. 
Now, even if you can do this, doesn't mean that you should. Before doing this, consider if you have other alternatives for doing what you want to achieve. Using php code inside template can run you into all kind of unpredicted security issues.

> **Comments:**
> **username_2**: +1 because it's all true... but as piotrpog mentioned, _this is playing with fire and you should try hard to avoid it!_  

---

### Answer by username_3 on 2023-12-20. Score: 0

I personally love separating querying and templating concerns and Craft's Twig implementation doesn't allow that very well. Writing queries inside templates doesn't sit well with me anymore after years in web development, so I went on to develop a small hidden plugin for Craft that allows a similar experience as Laravel's View Composers for Blade (hidden plugins start with an underscore character, they shouldn't, display in Craft's admin). In such, you can create a class that has the same name as your template to pass data to it before rendering. You can look it up here: https://github.com/guimauve-creative/craft-twig-view-composers
This allows to create PHP classes with a "compose" function where you can store some logic to abstract it from your view. It's not a controller per se because it runs at a higher level, when the request has already been treated, so that's why it's called a "view composer".
 composers/blog/Entry.php
 *
 * Element queries are made with PHP to
 * avoid using their twig counterparts
 * @see https://craftcms.com/docs/4.x/element-queries.html
 */

namespace guimauve\composers;

use craft\events\TemplateEvent;
use craft\elements\Entry;
use Craft;

class Index
{

    /**
     * @param      TemplateEvent $event Object passed by View::EVENT_BEFORE_RENDER_TEMPLATE
     * @see        https://github.com/craftcms/cms/blob/a1b232ea1888f131bb7626a5bdaff0f5fa2f4469/src/web/View.php#L1891
     * @see        https://github.com/craftcms/cms/blob/2eac9249964ccc553bf841c79b9ee44d58f16b61/src/events/TemplateEvent.php
     *
     * @return     void
     */
    public static function compose(TemplateEvent $event)
    {
         $locations = Entry::find()->section('shop')->relatedTo($selectedCity)->with([
            [
                'featuredImage', ['withTransforms' => ['x870']]
            ]
        ])->collect();
        $event->variables['locations'] = $locations;
    }
}

In other words, what this plugin does, is basically just look inside a specific folder if there's a class that contains a file with the same name of the template that's being executed. For "templates/blog/_entry.twig", it will look, load and execute a "compose" function on a PHP class if it's found at "composer/blog/Entry.php".
The compose function receives the only variable that we had access to which is the TemplateEvent $event variable, but lucky for us, this variable contains all the data that craft has pre-parsed for the template and we can graft anything onto it through the "variables" array index. If I collect blog entries, for example, and add them to the $event->variables['blogs'] array index, it'll be available in my twig templates as "blogs". Since all the database query functions we usually see in Twig are available in PHP too, we can use these counterparts and keep our code as clean as possible with better separation of concern.
Happy coding!


---

