I have a common header.php to include in virtually every page of the website. I have relative links to different resources in the header.php file. As soon as I include it in other pages which are located in different sub-folders under the root folder, some of the links would break. I can make all the links in the header.php absolute. Now another problem pops up: If you move the application to another domain and put it somewhere under the wwwroot, the absolute links will not work. I couldn't find a way in PHP to extract the part of the URL which is the root for this application. I ended up define a variable for the application root and prefix every link inside header.php with this variable. This way, I only need to change one variable when this application is moved from one place to another.
I am wondering if there are other better ways to handle this kind of situation.
Your feed back would be much appreciated.
Edit: hoping to receive more feed back.
You write it's a common header.php file, like with the central variable, you can do make use of the <base> HTML element - but this is limited to HTML.
You can create yourself a mapping function that is able to resolved absolut URLS to the request URI, or that is able to resolved relative URLS to the context they come out of so that they can be mapped absolutely relatively to the request URI again.
Then you can implement a output filter that is handling URIs on it's own and you can do some special prefixes for special treatments.
Related
I don't get it.
When trying to include files from different directories, i'm sure i must be missing something real simple.
Site structure is like this.
if i include("includes/header.php); from inside the /reports/top_sellers_report.php file, the call to the css file doesn't work.
To make it work i must put ../styles/styles.css
But then, if i open "product_dtails.php from the root, it too includes the header, and then the css file won't load and i need to remove the ../ to make it work.
I can't win...
Am i missing something? 4 hours of searching online suggests i am!
Your problem is not really PHP-related. Just look at the URLs:
http://www.example.com/
http://www.example.com/reports/
http://www.example.com/styles/styles.css
Depending on where you are on your site, the relative path to styles.css might change, thus when you access http://www.example.com/reports/ you have to use ../styles/styles.css, wheras in http://www.example.com/ you have to us styles/styles.css.
Probably the easiest way to fix your problem is either by using the absolute URL like http://www.example.com/styles/styles.css or the base-path /styles/styles.css instead of ../styles/styles.css. I recommend the latter.
I think you should look into using an MVC approach as this would probably help you organise your code better:
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
The include statements are evaluated on the server, so wherever you are including the file from, you need to specify it relatively from there. The CSS 'include' is being evaluated in the browser, so you need to make the file path relative from that directory.
I suggested looking to the MVC approach as it helps you to manage your code and separate the different parts of your website into distinct parts which should help you avoid this issue.
I suppose you can refer to you stylesheet absolutely though (ie http://www.mywebsite.com/dir/dir2/stylesheet.css) on each page and that would also work.
as far as I know, include is relative to your index so you have root/index.php
within index.php you should use include("styles/style.css")
within includes/header.php you'll need to add the ../styles to redirect you to root and then to your styles folder and so on
if you open directly product_dtails.php it will act like the index.php, so you need to just use styles/style.php
I have several files in my web folder, including these two:
/mydocroot/include/somesubdir/include.inc.php
/mydocroot/include/settings.inc.php
where somesubdir is a symbolic link to another directory on my disk, to a path named, eh, let's say /anywhere/else.
Inside include.inc.php, something like this is written:
<?php
require_once "../settings.inc.php";
?>
In my opinion, that should include /mydocroot/include/settings.php... But guess what happens: PHP tries to include /anywhere/settings.inc.php, instead of /mydocroot/include/settings.inc.php.
It seems like PHP automatically resolves symbolic links.
How can I avoid this and include my settings.inc.php file?
I just had a similar issue. You can do it by using $_SERVER['SCRIPT_FILENAME'] variable, that displays the requested file, so in your case it will be /mydocroot/include/somesubdir/include.inc.php, even if somesubdir is a symbolic link. To include a file that is one level lower instead of doing
require_once "../settings.inc.php";
do this:
require_once dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR."settings.inc.php"
Documentation about $_SERVER variables
The most straight forward solution is to always use absolute paths. There are multiple ways you can do this, from hard coding the path every time you need it, to hard coding the path once in the top of your script and referencing that, to dynamically figuring it out and setting it once at the top of your script.
The third option is what most off the shelf CMSs use to be able to run without complete knowledge of your file structure.
Why is it that you're using a symbolically linked directory in this manner?
The solution is to create a basepath variable. The best way to do this is to include the following at the top of your script and then reference it
$basepath = dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR;
You can then reference the basepath in your includes, requires, etc. Therefore,
include "../myscript.php";
Would become,
include $basepath."myscript.php";
If you are back ticking further, you will have this:
include "../../myscript.php";
Would become,
include $basepath."../myscript.php";
You must nest the dir_name functions twice, plus one more time for each additional folder you need to backtick through. You MUST get all the way back to the folder where the symbolic link exists.
I consider this issue a major design flaw with PHP. I can't think of a single instance where accessing backticked files relative to the actual file would be desirable. In all situations, including virtual hosting, it ONLY makes sense to regress back along the linked path, never the target path.
You can use is_link to check if a file is a symbolic link. If it is, use readlink to get the absolute target.
But, in ten years of php development I've never had cause to use symbolic links. As Jason suggests, I've always defined or deduced an absolute path once, then used that throughout my app to make all file paths absolute.
Hello I am trying to make a little spider.
While I was building it I came across a problem where I need to check if a link is a root domain link or a subdomain link.
For example:
http://www.domain.com or
http://domain.com
http://domain.com/index.php
http://domain.com/default.php
http://domain.com/index.html
http://domain.com/default.html
.
.
etc
are all the same.
So I need a function actually that takes the string url as an input and checks if it's the root or homepage whatever you like to call it of a site.
As noted in comments, this is really a basic aspect of coding the spider. If you intend to code a general purpose spider, you'll need to add means to resolve URLs and detect if they point to the same content and in what way (through a redirect or simply through duplicate content), as well as what kind of content they point to.
You need at least to handle:
relative paths
GET-variables that are in one way or another significant to the web page, but does not render differences in the content.
Malformed URLs.
JavaScript related information in the href attribute.
Links to non-HTML material -- direct download links to PDFs, images etc. (detect it on extension isn't always enough, what with PHP scripts delivering images).
These are just some of the aspects but it all comes down to the point that the kind of detection your after have to be a fundamental part of the spider if you intend to use it in any kind of generic manner.
Currently, I have a system that actively generates the pages on my site using PHP, more or less like so:
index.php ------include(query.php);-----> query.php grabs content from a file that corresponds to index.php
Query.php simply assembles the page from the mentioned index.php file and from header, footer, and navigation files.
The index.php file acts as a sort of proxy or label if you will so that when users visit the site, instead of having urls like "query.php?page=index" they have real pages.
The issue of course is that this is a bit convoluted. For each page of the site, I need 2 files: the "wrapper" file (such as index.php) and a content file to which it corresponds. I'd like to only be using a single file. The issue is that the single file should only contain the content of the page - not structure, header, footer etc.
So, what I'd like to be able to do is to be able to have index.php contain ONLYand a paragraph for example. When it is accessed, somehow PHP kicks in and applies a template and the header and footer.
Is PHP too high level a language to be able to do this? I know it is often done with Tomcat and java servlets, but I thought it would be cool to do with PHP.
EDIT: Important point, I don't want to use GET variables.
It's a bit hard to tell what you're trying to do, but have you looked into using a framework such as Kohana or Synfony? This will do pretty much exactly what you're asking.
If you're looking for a good template system, I suggest PHPTAL.
Failing that, it doesn't sound like you need to do anything that special. On the index.php page, why not just include header.php, the content, and footer.php? Short of using auto_append_file and auto_prepend_file, you can't add content to the page that is not explicitly in the code.
It sounds like what you want to do is route all requests through a single point (like frameworks do). Let's call it main.php.
On main.php you would have:
include header.php
include $_SERVER['PATH_INFO'] . ".php" //Requested file from URL. TODO handle this better
include footer.php
Then you would route all requests (using your server configuration) to "/main.php/pagename." Then pagename would only need its respective content.
In my php script I created a constant variable that defines the base url to be put in my hyperlinks, but do I really need this?
Here is an example of what I mean.
I have this:
// base url is only defined once and reused throughout
define("__BASE_URL","http://localhost/test1/");
print '<a href="'.__BASE_URL.'index.php?var1=open/>Open</a>';
(I have a lot of these spread throughout my script.)
I tried this and it works:
print '<a href="index.php?var1=open/>Open</a>';
So which way is the proper way on doing this? I noticed the second way even works on loading images, css, and javascript files.
It really comes down to how you're structuring your site. Relative URLs are great (by doing href="index.php" you're reallying saying href="./index.php"), but they can start to become messy when you begin spreading pages over multiple directories.
Personally I like to base all of my relative URLs off of the root directory, meaning that all of my URLs start with a slash ('/'). That way it doesn't matter if my script is in / or /admin, as I will always have a constant reference point - the document root - as opposed to some relative directory in the structure.
Your first example, storing document paths in variables, really starts to come in handy when you begin developing larger systems where you want the paths to be configurable. For example, maybe you want your system admins to be able to define where images are pulled from, or where the cached downloads are.
So really consider your use cases and size of your system.
Also keep in mind that if you ever move the script to another server that your URLs and directory structures may change, which could cause havoc (ex., you might have your script moved to a different subdomain, into the document root, etc.). A lot of people will drop in Apache's mod_rewrite in this case.
It depends. Without the __BASE_URL, your link will be relative to the current document. In your case, that means index.php must be in the same directory as the file that has the index.php link on it.
If you have the __BASE_URL, then the link will work no matter where its containing file is located (i.e. doesn't have to be in same directory as index.php).
Another option is to use a starting slash only. Then your link will be relative to your domain root:
print '<a href="/index.php?var1=open/>Open</a>';
In other words, the above link would point to http://localhost/index.php.
It sounds like your question is regarding absolute vs relative URLs. Are you going for portability? It's generally best to use relative URLs, especially if you plan to work in a test environment and then later transfer files to production.