Jump to content
PrinceTaz

PHP Templating

Recommended Posts

Okay so I just finished designing a template and I want to begin coding but I want to separate the logic from the template as per suggestions I've received. Now I have the separate files that are ready to be included, but how can I include it so that it updates globally. What I mean is this for example.

In my header.php, I have included "style/navbar.php". Now from the root directory that's fine. The problem comes when let's say I'm working inside viewpost.php that is actually inside /style and that file includes header.php which includes style/navbar.php. So now viewpost is looking for style/style.php. How do I make php know where the include files are globally and update that directory for each query? I hope I explained this properly.

Share this post


Link to post
Share on other sites

Use absolute path names in all scripts. You can even set a global variable with the absolute path name and use that in all scripts.

Share this post


Link to post
Share on other sites
Posted (edited)

I personally use root-relative links (vs absolute paths). That way if the domain name ever changes, you don't need to go through all your pages to update the links. I'm guessing that you are using "require" or "include" to import the information from scripts like navbar.php. To streamline those lines of code, you could consider setting the include path. More information can be found here:
https://www.php.net/manual/en/function.set-include-path.php

 

10 minutes ago, PrinceTaz said:

What do you mean by absolute path?

Absolute path would be something like "https://www.yourdomain.com/style/navbar.php".

Root relative would be "/style/navbar.php".

Edited by cyberRobot
formatting

Share this post


Link to post
Share on other sites
Posted (edited)

I should mention that you'll need to use something like $_SERVER['DOCUMENT_ROOT'] to reference the root value when importing code with things like "require" and "include". For example

require "{$_SERVER['DOCUMENT_ROOT']}/style/navbar.php";

Without the $_SERVER variable, you'll get an error. Also, I just tried using an absolute link (e.g. https://www.yourdomain.com/style/navbar.php). Apparently, my server is configured to disallow URLs within things like "require" and "include". I don't know if that's a common configuration, but it's something to be aware of.

Also, I've read a number of recommendations saying that PHP code should be stored outside of the root. Of course, that's not possible for all PHP since something needs to import the code into your web pages. However, code like your includes seem like perfect candidates for things to store outside the root. I don't know if it's possible to point absolute paths to something outside the root. I know that root-relative links can. In case you're interested, here's one explanation for storing PHP scripts outside the root.
https://www.php.net/manual/en/security.php#33627

Edited by cyberRobot
minor corrections

Share this post


Link to post
Share on other sites
4 hours ago, cyberRobot said:

I should mention that you'll need to use something like $_SERVER['DOCUMENT_ROOT'] to reference the root value when importing code with things like "require" and "include". For example


require "{$_SERVER['DOCUMENT_ROOT']}/style/navbar.php";

Without the $_SERVER variable, you'll get an error. Also, I just tried using an absolute link (e.g. https://www.yourdomain.com/style/navbar.php). Apparently, my server is configured to disallow URLs within things like "require" and "include". I don't know if that's a common configuration, but it's something to be aware of.

Also, I've read a number of recommendations saying that PHP code should be stored outside of the root. Of course, that's not possible for all PHP since something needs to import the code into your web pages. However, code like your includes seem like perfect candidates for things to store outside the root. I don't know if it's possible to point absolute paths to something outside the root. I know that root-relative links can. In case you're interested, here's one explanation for storing PHP scripts outside the root.
https://www.php.net/manual/en/security.php#33627

Here is my code: 

<?php
define("BASE_URL", "/Forum");
define("ROOT_PATH", $_SERVER["DOCUMENT_ROOT"] . "/Forum/");

But when I use BASE_URL, it doesn't work properly when including things from "includes" and I have to use ROOT_PATH. But when I'm including things in paratheses such as in tags, only BASE_URL works. I don't understand why that works.

Share this post


Link to post
Share on other sites

Also i want to know this. 

So I made a template file called viewthread_layout.php. Now I want to create the logic file, viewthread.php that is actually going to run everything. How do I link the two? I want to include the viewthread_layout.php inside viewthread.php because when they click the thread, the url will be /viewthread.php but in layout.php, the content will depend on the scripts in viewthread.php. How do I link each other?

Share this post


Link to post
Share on other sites
7 hours ago, cyberRobot said:

require "{$_SERVER['DOCUMENT_ROOT']}/style/navbar.php";

I've typically used something along the lines of this:

require_once(dirname(__FILE__).'/style/navbar.php');

I don't know if it's better or not, but it does make me feel like I've got more control over the file structure and as though there's less of a chance of somehow injecting "../../{whatever nefarious thing}" into $_SERVER['DOCUMENT_ROOT']. Also, (really no point in lying here) I don't even know if it's possible to inject into$_SERVER['DOCUMENT_ROOT'], but I know that $_SERVER['PHP_SELF'] can be spoofed, so I think it may just be possible. Maybe I'm just being paranoid.

Share this post


Link to post
Share on other sites

It's possible for $_SERVER['DOCUMENT_ROOT'] to not be what you expect, but unlikely.   Any issue with it would likely be due to a server configuration issue rather than an attempted attack most likely.

dirname(__FILE__) can be replace by __DIR__ since 5.3.

@PrinceTaz, create yourself a single file such as common.php that you can include into all your pages.  That file can then take care of setting up your environment for your scripts such as setting the include path, defining the path to your files, etc.  For example:

<?php

set_include_path(__DIR__.'/templates');

function render($__template, $__vars){
    extract($__vars);
    require 'header.tpl';
    require $__template;
    require 'footer.tpl';
};

Then in your individual page files you can use __DIR__ to build a path to that common file and include it.   With the include path then configured, everything else can be included with a simple relative path.   Given a directory tree then such as:

|   common.php
|
+---public_html
|       about.php
|       index.php
|
\---templates
    |   footer.tpl
    |   header.tpl
    |
    +---about
    |       index.tpl
    |
    \---home
            index.tpl

Then your index.php page could be:

<?php

require __DIR__.'/../common.php';

render('home/index.tpl', ['PageTitle' => 'Home']);

And about.php page could be:

<?php

require __DIR__.'/../common.php';

render('about/index.tpl', ['PageTitle' => 'About me']);

 

Share this post


Link to post
Share on other sites
35 minutes ago, kicken said:

dirname(__FILE__) can be replace by __DIR__ since 5.3.

Couldn't even begin to say why, but I always forget about __DIR__. It's weird, honestly.

Share this post


Link to post
Share on other sites
On 6/6/2019 at 8:50 PM, kicken said:

It's possible for $_SERVER['DOCUMENT_ROOT'] to not be what you expect, but unlikely.   Any issue with it would likely be due to a server configuration issue rather than an attempted attack most likely.

dirname(__FILE__) can be replace by __DIR__ since 5.3.

@PrinceTaz, create yourself a single file such as common.php that you can include into all your pages.  That file can then take care of setting up your environment for your scripts such as setting the include path, defining the path to your files, etc.  For example:


<?php

set_include_path(__DIR__.'/templates');

function render($__template, $__vars){
    extract($__vars);
    require 'header.tpl';
    require $__template;
    require 'footer.tpl';
};

Then in your individual page files you can use __DIR__ to build a path to that common file and include it.   With the include path then configured, everything else can be included with a simple relative path.   Given a directory tree then such as:


|   common.php
|
+---public_html
|       about.php
|       index.php
|
\---templates
    |   footer.tpl
    |   header.tpl
    |
    +---about
    |       index.tpl
    |
    \---home
            index.tpl

Then your index.php page could be:


<?php

require __DIR__.'/../common.php';

render('home/index.tpl', ['PageTitle' => 'Home']);

And about.php page could be:


<?php

require __DIR__.'/../common.php';

render('about/index.tpl', ['PageTitle' => 'About me']);

 

What if I'm including from multiple directories? Such as includes and templates? Also can you explain what the "render" function is doing?

Share this post


Link to post
Share on other sites

Thanks for the tip maxxd and kicken!

I was just looking at switching $_SERVER['DOCUMENT_ROOT'] to dirname(__FILE__) and/or __DIR__. Be aware that they may not return the same value. The $_SERVER variable returns the value for the root folder. The other options return the value of whatever directory the user is in, which may or may not be the root folder.

If the user is viewing "https://www.yourwebsite.com/about/", for example, __DIR__ will return something like "/home/webuser/yourwebsite.com/about". That's not going to work if I'm looking for "/home/webuser/yourwebsite.com".

Perhaps using __DIR__ would be a way to make sure the SERVER value isn't corrupted.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.