Problems with pointing to files on local server versus remote - php

I'm having a really silly issue... basically I'm working on a site on a localhost, and a remote host... I am including files by doing the following:
<script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script>
This works a treat locally. However on the remote, while its not live, the site address is (pseudo) xxx.xxx.xxx.xxx/~user and so obviously, the js folder is xxx.xxx.xxx.xxx/~user/js/ which means my /js/jquery... include isn't going to work.
Obviously you're thinking I just remove the forward slash at the start of the /js and simply do a relative src - the problem with this is that I'm using mod_rewrite with clean urls, so sometimes when the file which includes the above js src is being called from a few directories deep (or so the computer thinks) ie url.com/blah/blah/blah/ so with a relative src, its going to try url.com/blah/blah/blah/js.
I'm on a php environment and I'm just wondering what the least complex approach to all this is. ie $_SERVER['document_root'] . '/js/jquery....' is something my feeble mind tried but as you the expert probably know - its going to bring up a bunch of irrelevant unix directories and not just go to the current site root.
Any ideas?

When I'm working on various hosts with the same source code, I usually define constants for this sort of thing.
define('SITE_ROOT', '/');
or
define('SITE_ROOT', '/~user/');

Or, you could use this function. I haven't tested it extensively, but it works in the test I just performed. It returns the root relative url with a trailing slash.
function get_root_relative_dir()
{
$root_dir = $_SERVER['DOCUMENT_ROOT'];
$script_dir = dirname($_SERVER['SCRIPT_FILENAME']);
return substr($script_dir, strlen($root_dir)) . '/';
}

Related

PHP - Relative path to folder?

I am using an MVC codeigniter for a project I am working on. It is running on localhost just find and has a defined base_url='http://localhost/app/.
When running on the local machine, everything is working fine as expected and the images etc have a path that looks like: <link rel="stylesheet" href="http://localhost/app/assets/css/bootstrap.min.css">
The issue I am facing is when I use a VPN on my phone to look at the site. When on my local network, I type in the IP address of the server to load the website. This then causes images / css etc to still try and load from http://localhost and thus does not load them.
Is there a PHP variable that I can use that will get me the path to the folder the files are in? ie. ../../assets/bootstrap.min.css?
I tried using things like $_SERVER["DOCUMENT_ROOT"] but this gives me the full path /var/www/html/app/assets/css/ which again, isn't valid when I try to load this from another source such as my VPN.
How could I go about solving for this? Is this a path issue or something with the server I need to look into?
When you are wanting to collect files within the website you do not need to specify the url.
So if you have a domain whether it be localhost or a fqdn it doesnt matter and makes websites "portable"
Your links/images/script uri's can all be called relatively.
<a href="relative/path/to/file.html">
<img src="path/to/image.jpg">
<link rel="stylesheet" href="path/to/file.css">
<script src="path/to/file.css">
Doing this will overcome the portability issue, you will do the same in php some of the functions require the absolute path and those are documented but many allow you to use relative paths if you need a file from an adjacent directory you would use ../path/to/file etc.
Defining the path constant.
define('ROOTPATH', '/path/to/webroot');
From here I can combine my constant with the relative path wherever needed:
ROOTPATH . '/path/to/file'
I too faced the same issue. There seems to be a problem in the slash between views and html. Instead of back slash it contains forward slash. Work around: go to index.php and stop error logging by defining -1 to 0 as given below according to the environment.
Time being solution/work around:
if (defined('ENVIRONMENT'))
{
switch (ENVIRONMENT)
{
case 'development':
error_reporting(0);
Error message:
Warning: include(D:\xampp\htdocs\IPT\application\views/errors\html\error_php.php)

dirname(__FILE__) adds path after my domain

Here's my problem using the PHP function dirname()
Let me first explain, I'm working on a website where I defined a constant as follow :
define('ROOT', dirname(__FILE__));
That worked well on a shared hosting, but I had to move the website on a dedicated server and now some files I try to call with an absolute link return 404. When I look what path they use, something like this appears :
http://myIp/var/www/myWebsite/[...]/image.jpg
What happens is that, my 'ROOT' constant is '/var/www/myWebsite' but in place of 'Replacing' my domain, it's added at the end of it. Which makes no sense since my Apache VirtualHost sends all requests towards 'myIp' to the local folder '/var/www/myWebsite'.
I don't know if the mistake is either from my PHP code, or my Apache VirtualHost.
Thank you for your help, I'm sure it's something stupid but I can't figure what I did wrong :)
I think you are confusing server paths with site paths.
You would not want to use dirname to give you a path for a web asset.
What you could do if you really want to do it this way is to remove the path to your web root.
This might work:
define('ROOT', str_replace('/var/www/myWebsite/', '/', dirname(__FILE__)));

What does the "/" in php require/include mean?

When I use require("/toinclude.php"), what does the "/" mean?
Is it the root dir of my ubuntu?
or is it the www directory apacheset for me?
or is it the path of current file? this seems to be true...
What's more, I really get confused by the use of path in PHP. Is it so that the "/" in require()/include() means the current directory, the "/" in system(...)/exec(...) is
the root directory of Linux, and the "/" in html code <form action="/processpost.php"> is the "www" directory Apache set for me?
In PHP (which is server side), any path that starts with / (at least on Unix-based systems) is the filesystem root. In most (if not all) cases, this is not what you want.
In HTML (which is client side), '/' is the URL root. That is: it is placed directly after the domain name. E.g. /process.php in a HTML file fetched from http://example.com will redirect to http://example.com/process.php. This could be the www-root, but might also be something else depending on settings in the server.
include and require use an include path to get files. If you do not provide a full path (that is, you omit the / at the beginning`), PHP will scan all directories it finds in its include path, starting in the current directory. Often, the path to PEAR modules is in that path, so code like this:
include("SomePearModule/Module.class.php");
works, even though it is not in your website's tree.
More can be found in the documentation.
It's the literal server-side (file system) path. Well, not always literal.
It depends on your server setup. If PHP is running in a jailed chroot, then / as far as PHP sees it might actually be something like /var/web/chroots/domain.com/ or similar.
Most often, you want some kind of configuration file that figures out where libraries and stuff are, based on relative paths of where the script is actually executing, then pass that information to require() and require_once() respectively.
Something like:
<?php
$base = dirname(__FILE__);
$Libraries = $base . '/libraries';
require_once($Libraries . '/Library.php');
?>
If you use any kind of modern framework, this is generally handled for you by whatever means it provides to load things. It's good to just make sure that any calls to require() or require_once() don't have to change depending on where you install the app, it's all relative to where it's executed.

PHP path issues (localhost and server)

How do you guys handle the path of files to work either localhost and server without changing the variables?
For example, I have this:
$path = realpath($_SERVER["DOCUMENT_ROOT"]);
returns C:\xampp\htdocs
This would probably work on a online server, but doesn't work on a localhost, because I need to set the folder name of my project.
So, in my 100 files (for example) I would have to change to whenever I want to work in localhost:
$path = realpath($_SERVER["DOCUMENT_ROOT"]) . "/myproject/";
So I thought about a variable with a certain condition which would understand if it's localhost or server.
$path = (strpos(realpath($_SERVER["DOCUMENT_ROOT"]), "xampp") == false ? realpath($_SERVER["DOCUMENT_ROOT"]) : realpath($_SERVER["DOCUMENT_ROOT"]) . '/myproject');
And all I had to do:
<link href="<?php echo $path . '/css/bootstrap/bootstrap.css';?>" rel="stylesheet" type="text/css"/>
The above code does not work (at least in localhost, I haven't tried in a real server), because I get the following errors on console:
Not allowed to load local resource:
file:///C:/xampp/htdocs/myproject/css/bootstrap/bootstrap.css
Which I understand, so I have tried to change my $path variable to:
$path = (strpos(realpath($_SERVER["DOCUMENT_ROOT"]), "xampp") == false ? realpath($_SERVER["DOCUMENT_ROOT"]) : 'http://localhost/myproject');
And I get in the console:
Warning: require_once(): http:// wrapper is disabled in the server configuration by allow_url_include=0 in C:\xampp\htdocs\myproject\backend\orders.php on line 6
Is there any better way?
The most straightforward approach is to just create a local site with the same folder structure than your live site. I suspect you're doing it that way only because you aren't aware of Apache virtual hosts.
In any case, it's always practical to abstract paths as much as possible and constants are always a good choice. I typically define two:
WEB_ROOT to be used in URLs (in my case it's often just /)
FS_ROOT to be used in file system paths
You can feed them with hard-coded values in a settings file or dynamically calculating them. FS_ROOT is trivial to populate: you can use __DIR__ or dirname(__FILE__) for very old PHP versions.
Surprisingly, $_SERVER["DOCUMENT_ROOT"] does not provide accurate info in all hosting services.
Edit #1: I've appreciated a little base misconception in some of your comments so I'll try to shed some light on it.
Finding stuff on the Internet is not the same as finding stuff in your hard disc. The former makes use of URLs:
http://example.com/blog/latest-news?page=3
The latter makes use of file system paths:
/home/alice/pictures/kitten.jpg
C:\Users\Bob\Desktop\Shopping list.txt
In a web based PHP application you normally need to use both and you need to know the difference. You cannot use a URL to grab random files from a computer (not even yours) and you cannot use a file system path to grab anything from someone else's computer. This:
<link rel='stylesheet' href='C:\xampp\htdocs\myproject/css/bootstrap/bootstrap.css'/>
... is plain wrong because your linking a public resource with a file system path that will only work in your PC.
And one more thing... Most operating systems have adopted the convention to consider . and .. special directory names. That convention has been extended to URLs. But you must handle them as any other path component: it's backend/.. and not backend.. for the same reason that foo/bar is not the same as foobar.
Edit #2: Even if you don't use class auto-loading or the include_path directive, it's trivial to load your application wide settings file, either with absolute paths:
require_once(__DIR__ . '/../conf/configuration.php');
... or relative paths:
require_once('../conf/configuration.php');
IHMO, doing this once per script, in the top level PHP file, is a huge benefit over calculating all application paths every single time you use them.

Why do link paths in JavaScript not require a precedding / but paths in PHP includes do?

Sounds nit picky but this had me hung up for about an hour or so.
I have a path set like this in JavaScript
const JAVASCRIPT = 'host/source/ArcJB.js';
which renders in my document like this:
<script type="text/javascript" src="host/source/ArcJ.js"></script>
If I put in a preceding / it breaks the link.
In PHP, for server-side paths I use:
<?php
include_once getcwd() . "/host/source/class.ControlEntry.php";
If I don't put in the / it breaks things.
I guess conceptually how am I suppose to know this so I don't have to pull my hair out with trial and error?
Also noted:
Paths inside my .js file work with either a / or not a / preceding the path.
These are used for image lookup or ajax calls.
You should be aware that the paths you pass to include_once are resolved on the server itself while the paths in Javascript are resolved by the browser. Both basically follow the same rules:
paths starting with / are resolved absolutely. On the server, this is the root directory (i.e. the topmost directory). In the browser, this is basically concatenating the host and the path that you are specifying.
paths not starting with a / are relatively resolved, i.e. against the current directory on the server and against the path in your browser.
Realize that getcwd() returns a directory like /var/www. If you then just concanate host/source/class.ControlEntry.php to it, it will yield /var/wwwhost/source/class.ControlEntry.php. On most (if not, all) PHP SAPI's, you can leave out the getcwd() thing when including a file as the current directory is already being searched when including files. In this case, you do not need the / either.
Finally, the server file paths do not have to match the URLs! http://example.com/script.php can be located at /var/www/script.js. If you refer to /script.php in a HTML file, it will be resolved correctly. On the other hand, you should not try include "/script.php", that will search for a file script.php in the root of your filesystem which is most often not what you are looking for.
Preceding slash is used to denote the path should be considered as an absolute path, which means,
For your Js path, which resides in a HTML file which is parsed by a browser to render its content, it should append what you wrote to the domain to get the file. And if your Js file is located relatively to the current page your snippet is located, the link may break.
For your php file, it is located in a path which can be accessed by following system root to host/source/class.ControlEntry.php
You know where you're files are located. Use relative or absolute paths to them, and it will work both in PHP and JavaScript.
In your examples, the preceding / will make the paths point to somewhere else, breaking the application. In your PHP example, you especially concatenate the path string - it will depend on the evaluation of getcwd().

Categories