First, I know basically zero php, I usually do jsp but I have to modify a footer for a wordpress site we have.
The site currently is hosted at www.mysite.com/wordpress and has the following line:
<?php readfile('http://www.mysite.com/css-imports.jsp'); ?>
and because I am doing this on development I keep having to change it to:
<?php readfile('http://local.mysite.com/css-imports.jsp'); ?>
When I do that the wordpress url is local.mysite.com/wordpress.
How can I from php insert local.mysite.com or www.mysite.com based on the domain that is serving the page?
Thanks.
You need a base URL variable (of which I'm certain Wordpress will have one, most frameworks do). Have a look at this answer here.
Hard coding a domain in like that when it relates to your server is not a good idea, because as soon as you move your code - breaky breaky. So to use their example, you'd do something like this:
<?php readfile(get_bloginfo('wpurl') . '/css-imports.jsp'); ?>
Might need a bit of playing around with, have a look at the Wordpress Dev Docs and find something that suits you if this doesn't:
http://codex.wordpress.org/Function_Reference/get_bloginfo
http://codex.wordpress.org/Function_Reference/home_url
You could set up a simple config file that will differ between the local and production servers. All you'll need to do is make sure the local copy doesn't get included when new code is pushed to the server.
Local copy of serverconfig.php:
<?php
define('SITE_HOSTNAME','http://local.mysite.com/');
?>
Off-site copy of serverconfig.php:
<?php
define('SITE_HOSTNAME','http://www.mysite.com/');
?>
Everything else will just need to include the config file and reference the constant(s) defined in it.
<?php
require_once 'serverconfig.php';
... code ...
readfile(SITE_HOSTNAME. 'css-imports.jsp');
?>
Note: if you're just reading static files that are located on the same webserver, you should just reference the local files, readfile('/css-imports.jsp');.
I usually just end up modifying my hosts file. I work with too many disparate customer systems locally (including WordPress and Drupal) and it seems like every system I've seen has templates/themes/plugins that don't reference the framework's base url variables, or uses hard-coded absolute paths, or uses relative paths that don't jive well with my server, or just something.
When you're done developing and need to load it into production, just comment out the hosts entry.
/etc/hosts
# map mysite.com to local host for dev reasons.
www.mysite.com 127.0.0.1
I think this will do the try for me
$_SERVER[HTTP_HOST]
Related
I'm trying out a lot of PHP example projects. For most examples I need to setup a VirtualHost in the Apache config (httpd-vhosts.conf) to get them working.
But sometimes I just want to copy or test a project, without going through the hassle of making another VirtualHost.
It would be nice if everything still works too when I try http://localhost/ProjectDir/ instead of http://ProjectDir/
In Phalcon I know how to fix the root directory, by changing the config or with setBaseUri(), but this is a bit inconvenient to change every time. It would be nice if this could be done automatically somehow. (I do realize that in this way I can not use absolute URLs or links inside the HTML (starting with /) since that would mean the root folder of the Apache server then but this could be solved with an automatically configured prefix-variable).
How do other developers handle this situation, or do you really choose between a virtual host or http://localhost/ProjectDir/ ?
Is there a way for a PHP script to detect if it's running in a
virtual host or in a subdir of localhost?
UPDATE
Found out I could use $_SERVER['SERVER_NAME'] to determine if it's 'localhost' or something else. Not very elegant, but it's a sufficient solution, I guess.
Within html views:
I like to use absolute paths from the document root for ease. (Relative paths are flexible but can get complicated.)
<img src="/images/foo.jpg">
Of course if I want to move the project into a sub directory, the path above will need to be adjusted. (We could use the html base tag, but that can have side effects.):
<img src="/subdir/images/foo.jpg">
We could use a variable in our views that we prefix to links and asset paths:
<?php
$base = '/subdir'; // Set somewhere.
?>
<img src="<?php echo $base ?>/images/foo.jpg">
To set the $base variable automatically, I sometimes assign it to Symfony/Component/HttpFoundation/Request::getBasePath(). (There are some other useful utility methods in that component.) Or use something similar from another framework/library/component.
Assigning a value in one place in a central configuration isn't that much of a hardship. I find prefixing paths within the views more of a pain.
In one of my development environments, I use a symlink from the directory root to the project directories directory root:
/var/www -> /sites/example.com/pub
And swap it as and when needed. You can avoid writing multiple virtual host configs that way and skip the other steps mentioned above.
However, configurable prefixes can be useful in other ways:
$base_cdn = 'http://cdn.example.com';
$base_nav = '/subdir';
$base_static = '//static.example.com/foo';
assuming the entry is index.php
function getVirtualHostPath(): string
{
$temp = str_replace("index.php", "", $_SERVER["SCRIPT_NAME"]);
return substr($temp, 1);
}
// "https://domain.example/subdir/api/v2/store/inventory" => "subdir/"
// "https://domain.example/api/v2/store/inventory" => ""
// "https://domain.example/subdir/api/v2/store/inventory" => "subdir/"
// "https://127.0.0.1/api/v2/store/inventory" => ""
Explanation:
dump $_SERVER super global in production (that uses virtual hosts) and filter out all keys that does not contain "subdir".
filter out all keys that are not present in CGI 1.1 specification
copy the same keys from development environment without virtual host.
$_SERVER["SCRIPT_NAME"] contains "/subdir/index.php" in prod and "/index.php" in dev. Removing "index.php" will return the virtual host path.
I am sure that this is a repost but I cannot find a question the same as what I want to find out. Essentially, whenever I am working offline, all URIs that I use across the site refer to offline locations eg 127.0.0.1/home.html however, when I go to upload the site, these URIs need to be changed to their equivalents eg example.com/home.html and I either need to go through all of the pages and update these references or use some php to insert the correct address at every point where an address is used. At the minute I am using something like this:
Top of every page:
<?php $offline = false; ?>
Link:
Home
But this seems like a poor way to achieve something which should be relatively simple. What is the standard way of keeping these references up to date. I considered using relative links everywhere but that proved to have problems (for example view includes don't work correctly) and I tried setting the base href to the homepage but that threw up other problems.
Any suggestions would be very much appreciated. Thanks.
$server=$_SERVER['SERVER_ADDR'];
// Local
if(strstr($server,'127.0.0'))
{
define('ROOT_PATH','http://127.0.0.1/');
}
// Server
else
{
define('ROOT_PATH','http://www.yoursite.com/');
}
Put this code in php file and include in every page.
And then:
Home
In this case you can put your files in folder too, for example:
define('ROOT_PATH','http://www.yoursite.com/mysite/');
Another way you could do it is using relative paths.
For files in the same directory you'd use ./ and for files above that directory use ../ This works for anchors in HTML and requires and includes in PHP.
As Waygood suggested, it sounds like you need to change your paths from absolute to either site root relative or relative paths. Example: 127.0.0.1/home.html would become just /home.html if using site root relative. Alternatively, if there's a reason why you must include absolute paths, you can set an environment variable on the server or a PHP constant that indicates the environment type and toggle links based on this value. Using environment variables has the added benefit of being able to keep the exact same code base on your dev and production machines and not having to resort to host or IP detection. Here's an example from zend framework's docs guide that I use:
defined('APPLICATION_ENV') || define('APPLICATION_ENV',
(getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
From: http://framework.zend.com/manual/1.12/en/zend.application.quick-start.html
A neat way that I have found to resolve this issue is to amend your HOSTS file so that it points example.com to 127.0.0.1 so that you can refer to example.com everywhere but be redirected to 127.0.0.1 until your development has finished.
Most of my website is in my root directory. And In that directory there is "css", "functions", "images" folder. Everything works fine when I include php files within index.php or any other root file. It includes it fine and executes it fine.
But problem occurres when I made folder "blog". So this is totally new and separate root folder with CMS and its own "root" files. And I try to include css from main root directory or some php files from "functions" folder in main root directory, Everything breaks down. I know I have to include it as ../functions/myfile.com. But this files includes some other files so it just wont work properly and won't be able to include other files properly.
Is there any idea how to fix this problem?
You can get to the root from within each site using $_SERVER['DOCUMENT_ROOT']. For testing ONLY you can echo out the path to make sure it's working, if you do it the right way. You NEVER want to show the local server paths for things like includes and requires.
Site 1
echo $_SERVER['DOCUMENT_ROOT']; //should be '/main_web_folder/';
Includes under site one would be at:
echo $_SERVER['DOCUMENT_ROOT'].'/includes/'; // should be '/main_web_folder/includes/';
Site 2
echo $_SERVER['DOCUMENT_ROOT']; //should be '/main_web_folder/blog/';
The actual code to access includes from site1 inside of site2 you would say:
include($_SERVER['DOCUMENT_ROOT'].'/../includes/file_from_site_1.php');
It will only use the relative path of the file executing the query if you try to access it by excluding the document root and the root slash:
//(not as fool-proof or non-platform specific)
include('../includes/file_from_site_1.php');
Included paths have no place in code on the front end (live) of the site anywhere, and should be secured and used in production environments only.
Additionally for URLs on the site itself you can make them relative to the domain. Browsers will automatically fill in the rest because they know which page they are looking at. So instead of:
<a href='http://www.__domain__name__here__.com/contact/'>Contact</a>
You should use:
<a href='/contact/'>Contact</a>
For good SEO you'll want to make sure that the URLs for the blog do not exist in the other domain, otherwise it may be marked as a duplicate site. With that being said you might also want to add a line to your robots.txt file for ONLY site1:
User-agent: *
Disallow: /blog/
Other possibilities:
Look up your IP address and include this snippet of code:
function is_dev(){
//use the external IP from Google.
//If you're hosting locally it's 127.0.01 unless you've changed it.
$ip_address='xxx.xxx.xxx.xxx';
if ($_SERVER['REMOTE_ADDR']==$ip_address){
return true;
} else {
return false;
}
}
if(is_dev()){
echo $_SERVER['DOCUMENT_ROOT'];
}
Remember if your ISP changes your IP, as in you have a DCHP Dynamic IP, you'll need to change the IP in that file to see the results. I would put that file in an include, then require it on pages for debugging.
If you're okay with modern methods like using the browser console log you could do this instead and view it in the browser's debugging interface:
if(is_dev()){
echo "<script>".PHP_EOL;
echo "console.log('".$_SERVER['DOCUMENT_ROOT']."');".PHP_EOL;
echo "</script>".PHP_EOL;
}
If I understand you correctly, You have two folders, one houses your php script that you want to include into a file that is in another folder?
If this is the case, you just have to follow the trail the right way.
Let's assume your folders are set up like this:
root
includes
php_scripts
script.php
blog
content
index.php
If this is the proposed folder structure, and you are trying to include the "Script.php" file into your "index.php" folder, you need to include it this way:
include("../../../includes/php_scripts/script.php");
The way I do it is visual. I put my mouse pointer on the index.php (looking at the file structure), then every time I go UP a folder, I type another "../" Then you have to make sure you go UP the folder structure ABOVE the folders that you want to start going DOWN into. After that, it's just normal folder hierarchy.
i had the same issue and found a code on https://css-tricks.com/php-include-from-root/ that fixed it
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/common/header.php";
include_once($path);
?>
None of the above answers fixed this issue for me.
I did it as following (Laravel with Ubuntu server):
<?php
$footerFile = '/var/www/website/main/resources/views/emails/elements/emailfooter.blade.php';
include($footerFile);
?>
Try to never use relative paths. Use a generic include where you assign the DocumentRoot server variable to a global variable, and construct absolute paths from there. Alternatively, for larger projects, consider implementing a PSR-0 SPL autoloader.
I have wamp setup on my windows box. Generally, when I bring a site down from the web, I create a folder inside my www folder for the site name. ex: c:\wamp\www\mysite. Once I have the folder, I copy down all the live files. The issue is that all the paths are then broken because my local folder isn't rooted.
What is the best way to setup paths so that if the site moves to a folder that isn't rooted, it will work easily?
I use a file (usually called something like config.php) to keep track of the root folder. My definitions (constants) look like this:
define('BASE_DIR','/wherever/whenever/');
define('LIB_DIR', BASE_DIR . 'lib/');
And then when you need to include a file
include LIB_DIR . 'aFile.php';
This would be something you do on a new site or if you have time to refactor your current site.
Create an include file, that has constants setup based upon whatever the root directory is... then in your code, use the constants you created to include files.
Also note, that when you are using directory "slashes", always use the build in constant DIRECTORY_SEPARATOR instead of hard coding it, this will allow you to go from WIndows to Linux seamlessly.
We use $_SERVER['DOCUMENT_ROOT'] to determine where we are in the filesystem and then simply append the folder name of our project to that. This works perfectly for us. You should always use a configuration.php where you define basic paths and URL's that may change when moving the project from one server/folder to another.
Option 1. Use <base href=""/> tag
Option 2. Use a config file, like #MattCan suggests
Option 3. Use a server environment variable, like #Bjorn suggests
Option 4. Create a virtual host on your apache, than you can create a domain who appoint exactly where are your app folder. Apache Doc here
I'm having difficulty with paths in a cms system I'm attempting to build, I've basically got a folder with my header.php and footer.php files inside.
These are included in index.php and work fine. But then when I attempt to use the same includes in a file within my admin sub directory, the images and CSS are broken, obviously because the relative path is now wrong.
So my question is, how can I overcome this?
After reading some of the other questions on here and various other sources, I think absolute paths are the way forward, but I've always used relative paths, so the various concepts of using config files to specify an absolute path are confusing me.
I usually manage to work things out for myself, but it's been a long day and Im stumped!
i usualy have a file called config in my application root and in it i define a constant for base path and a few others:
define('APP_BASE_PATH', dirname(__FILE__));
define('APP_FUNCTIONS_PATH', APP_BASE_PATH . '/functions');
and i include my files like
include (APP_BASE_PATH . 'includes/another_file.php');
include (APP_FUNCTIONS_PATH . '/function_file.php');
that way i can place my aplication in whatever directory, plus i can move files around without to much worries.
also using full path makes the include faster
I prefer setting the environment variables (in Apache, using .htaccess or the .conf). This way you can move all your files freely anywhere in webroot and it will have access to those variables.
SetEnv lib /library/folder/
SetEnv public /my/web/root/
SetEnv environ DEVELOPMENT
Also you can use the variable named 'environ' mentioned in the above .htaccess snippet to include a server specific file as config file in all of your scripts and set various variables there.
require_once getenv('lib')."Configs/Config_".getenv('environ').".php";
Enjoy your freedom!
or...
include($_SERVER['DOCUMENT_ROOT'] .'/includes/header.php');
Relative and absolute paths in PHP are a bit fragile because they depend not just on the current directory of the including file, but also the current working directory.
So you need a two-part solution.
Firstly, you need a redirector. Basically, this is an include file that serves as a single-point-of-call for all other pages. Its job is to go and include the rest of your infrastructure. All your pages call this redirector and only this redirector (but you can chain them).
This redirector now does
include_once dirname(__FILE__).'/include/include.php';
This lets you change your infrastructure's include file, or location and all you have to update is one file. The dirname() call solves all the relative and absolute problems and has it look for the next step relative to itself. And by definition this only changes when you change it, so it will always work.
The second part is a custom includer so you can call content by name with a function and it goes and gets the right file. Burying this in your infrastructure directory is where is goes. It then becomes a black-box that the pages outside this area call without knowing and without needing to know how it works or where it is. That removes the need for path constants to include page fragments because you have one place doing it all for you.
I have had this similar issue and posted this query in this link in SO. The URL is : Issue with PHP include with global path.
While working on the solutions given by people and looking at various threads (including this one - which I had quoted in my solution at the bottom section of my post), I had a way! I had posted the solution as well. It may help some one who is facing a similar issue.