1

I have an html file which works fine by itself. The html file contains some relative paths.

When I include the html file in php, I run into issues with relative paths.

The chart.html file has a script src like this:

<script src="./data/data.js"></script>

and index.php include looks like this:

include('./chart/chart.html');

The error I get in browser is failing on this:

X GET http://localhost/project/data/data.js 

Obviously the path for data.js is missing the chart folder. It should be like this: http://localhost/project/chart/data/data.js

Here is my folder hierarchy:

Sites/
  project/
    index.php
    chart/
        chart.html
        data/
           data.js

I know I can modify the html file and add chart to the path, but that will make the html file not to be viewable by itself. Basically the html file assumes the path is based on the current chart.html relative path. So what is the right way to have php include this html file and not mess up the relative paths?

apadana
  • 13,456
  • 15
  • 82
  • 98
  • Why not use absolute URL instead? – Basit Aug 09 '16 at 07:15
  • 1
    Try doing ``. From the error, I guess the `php` script starts looking from the current working directory and hence you get an error. – Vivek Pradhan Aug 09 '16 at 07:16
  • @VivekPradhan Your proposed solution would break the functionality of standalone `chart.html` file which is required. – Basit Aug 09 '16 at 07:17
  • http://stackoverflow.com/questions/12432913/how-to-use-relative-paths-for-included-files-such-as-css, I think this covers your issue – Sirjan Sharma Aug 09 '16 at 07:17
  • The browser will append the relative path (to the javascript file) to the path of the page it currently sees, and that path is `/project/`, *not* `/project/chart/`. – klaar Aug 09 '16 at 07:17
  • @klaar yes, exactly this is what happens. – apadana Aug 09 '16 at 07:20
  • @VivekPradhan The problem is that the html file won't be viewable by itself. – apadana Aug 09 '16 at 07:20
  • If you want to 'embed' the contents of `chart.html` into a page that has another relative path (like you are doing now), you need to make the paths to any file in `chart.html` absolute. If you do not do this, it's not possible to use the contents of `chart.html` in any other location, because the paths would be wrong. Be aware that you can just use paths relative to the root of the server, so not including the domain or address in the path. – klaar Aug 09 '16 at 07:26
  • 1
    Just as a side note, `include` in PHP is a language construct, not a function. Consequently, syntax is not `include($_SERVER['DOCUMENT_ROOT'].'/chart/chart.html');` (with brackets) but `include $_SERVER['DOCUMENT_ROOT'].'/chart/chart.html';` (without brackets). – Rounin Aug 09 '16 at 07:40
  • @Rounin: Brackets are things like `[` and `]`, while things like `(` and `)` are called braces. Subsequently, things like `{` and `}` are called curly braces. Is it possible that you meant braces instead of brackets? – klaar Aug 09 '16 at 09:50
  • I don't doubt your proficiency in English, @klaar. But when I say brackets, I mean brackets. See: http://meta.stackoverflow.com/questions/252503/are-british-international-english-terms-acceptable-e-g-brackets-instead-of – Rounin Aug 09 '16 at 10:10
  • @Rounin: as it now seems, I am wrong with what I thought were proper definitions for those things, so I hereby stand corrected! Interesting read with wildly differing opinions, though... – klaar Aug 09 '16 at 10:19

1 Answers1

4

The problem here is the discrepency between absolute and relative paths. By including it into some other path, effectively changing the path of chart.html, but NOT changing the relative path of the dependent files, you break the code.

There is the base tag https://developer.mozilla.org/en/docs/Web/HTML/Element/base that you could put in the head. However, that may make matters worse, since the other content your index.php might include will not work anymore, unless those use absolute paths. If you don't do this anyway, this might be a good solution.

The second solution would probably be to (programmatically) search for relative paths in your html and replace those paths with corrected paths on the fly. there are some weird cases where javascript is used in html and there may be some "anti-copy" protection js code, that will probably choke on this.

The third solution (depending on your use case of course) would be, to not include the html but instead put an iframe in your output, where you point to the correct path. Since it's loaded from the right path, relative paths should work again. (I'd prefer that one, especially if it's some kind of "preview" functionality you're after).

Another solution could be to put another index.php into the chart folder, that - by including (and making the original index.phps code flexible enough) - will do the same work as the original index.php, but as it is requested from a different path, everything is fine.

A different approach would be URL rewrites, where you could make it appear as if the index.php was in the chart directory (a redirect from the original call might be necessary). URL rewrites can be difficult, depending on your overall setup.

Those are my proposals, however, depending on what you actually want to do with your project, there might be more suitable solutions.

update to the extra index.php solution:

Note that this will only work for showing one project at a time, and not multiple simultaneously. Also this highly depends on what your index.php does or how it works. Let me assume it looks like this:

<?php
$project = !empty($_POST['project']) ? $_POST['project'] : '';
$projects = array('chart', 'otherproject');
if(in_array($project, $projects)) {
    include $project.'/'.$project.'.html';
}
foreach($projects as $p) {
    echo '<a href="?project='.$p.'">'.$p.'</a>';
}

Now, the new chart/index.php would do something like:

<?php $project='chart'; include '../index.php';

and you'd need to change your original /index.php to:

<?php
$project = !empty($project) ? $project : '';                   // <-- changed
$projects = array('chart', 'otherproject');
if(in_array($project, $projects)) {
    include $project.'/'.$project.'.html';
}
foreach($projects as $p) {
    echo '<a href="/URL/TO/ROOT/'.$p.'/index.php">'.$p.'</a>'; // <-- changed
}
Jakumi
  • 8,043
  • 2
  • 15
  • 32
  • Another solution could be to put another index.php into the chart folder, that - by including (and making the original index.phps code flexible enough) - will do the same work as the original index.php, but as it is requested from a different path, everything is fine. --> could you elaborate more on this? If it works it's the best idea. I tried it but index.php in the chart folder should still include the chart.html as ./chart/chart.html. The new index.php doesn't understand that it's sitting beside the chart.html. – apadana Aug 09 '16 at 07:43
  • @apadana Again, you can `include` using paths relative to the root instead of the current directory. – klaar Aug 09 '16 at 07:49