kauffee000 kauffee000 - 1 year ago 48
PHP Question

Why does my PHP include statement fail when I include the directory in the relative path?

I'm fairly new to PHP, and am still learning how some of the include/require functions work. I'm working on a plugin, and I'm trying to break up the main template into a few files to make it easier to read/maintain (if this is a bad idea, that's a whole other discussion). My plugin public folder looks kind of like this:

resources-plugin
├── includes
│ ├── class-resources-short-codes.php
│ └── index.php
├── index.php
├── public
│ └── partials
│ ├── resources-banner.php
│ ├── resources-filters.php
│ ├── resources-items.php
│ └── resources-query.php


In my class-resources-short-codes.php file, I have three working include statements:

add_shortcode( 'example-resources-sc', function () {

// Banner
include( dirname( __FILE__ ) . "/../public/partials/resources-banner.php" );

echo "<article class='resources flex-container'>";

// Filters
include( dirname( __FILE__ ) . "/../public/partials/resources-filters.php" );

// Resources
include( dirname( __FILE__ ) . "/../public/partials/resources-items.php" );

echo "</article><!-- /resources -->";

} );


Then, in the child template resources-filters.php, I have another include that is supposed to pull in the HTML from the resources-query.php file:


<?php

// Doesn't work
// include( "./resources-query.php" );
// include( plugins_url("resources-plugin/public/partials/resources-query.php") );

// Works
//include( "resources-query.php");
include( dirname( __FILE__ ) ) . "/resources-query.php";

?>

<div class="slide-container">Other HTML here.</div>


My question is - why do two of these methods work, but the other two don't? I know I'm a little confused on how file paths are determined when you're using nested include statements.

PHP version: 5.3.3
Wordpress version: 4.2.2

Thanks!

Answer Source

First thing first I'd recommend only using dirname() once at the top of your script if you need to. If you look in wp-config.php you'll see that they do something similar around line 80 like this:

define('ABSPATH', dirname(__FILE__) . '/');

in your case you could do something like this:

define('MYPATH', dirname(__FILE__));


add_shortcode( 'example-resources-sc', function () {

    // Banner
    include( MYPATH . "/../public/partials/resources-banner.php" );

    echo "<article class='resources flex-container'>";

    // Filters
    include( MYPATH . "/../public/partials/resources-filters.php" );

    // Resources
    include( MYPATH . "/../public/partials/resources-items.php" );

    echo "</article><!-- /resources -->";

} );

Now to the questions you asked:

include( "./resources-query.php" );

This does not work because by default PHP won't assume the directory you are in. Strangely PHP will allow you to reference a file in the same directory if you remove the ./ but try to avoid this behaviour as it is just confusing in general.

include( plugins_url("resources-plugin/public/partials/resources-query.php") );

The problem with the second example you gave is that you are trying to include a URL not a path. Some systems allow this, but by default most do not.

As a rule I would recommend always including files using absolute file names like you did in the examples that work. Maybe consider defining a constant like I mentioned and this should help make sure you are always pointing to the right paths. If you need some error feedback to explain things consider using require_once instead of include for testing purposes. And finally consider staying away from using paths that contain /../ as they will just give you headaches in the end.

Koda

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download