I have been working on a content management system (nakid) and one of my toughest challenges is the file navigation. I want to make sure the file paths and settings work on local and remote servers. Right now my setup is pretty much something like this:
first.php (used by all pages):
//Set paths to nakid root
$core['dir_cur'] = dirname(__FILE__);
$core['dir_root'] = $_SERVER['DOCUMENT_ROOT'];
//Detect current nakid directory
$get_dirnakid_1 = str_replace("\\","/",dirname(__FILE__));//If on local
$get_dirnakid_2 = str_replace("/includes/php","",$get_dirnakid_1);
$get_dirnakid_3 = str_replace($_SERVER['DOCUMENT_ROOT'],"",$get_dirnakid_2);
//remove first "/"
if(substr($get_dirnakid_3, 0,1) == "/"){
$get_dirnakid_3 = substr($get_dirnakid_3, 1);
}
//Set some default vars
$core['dir_nakid_path'] = $get_dirnakid_3;
$core['dir_nakid'] = $core['dir_root']."/".$core['dir_nakid_path'];//We need to get system() for this real value - below
The reason I also did it this way is because I want the directory that this program is sitting in to be anywhere on the server ie(/nakid)(/cms)(/admin/cms)
I'm positive I am doing something the wrong way or that there is a simpler way to take care of all this.
If it helps to get a closer look at the code and how everything is being used I have it all up at nakid.org
EDIT: Just realized what I have at nakid.org is a little different than my newly posted code, but the same idea still applies to what I am attempting to do.
By and large, it looks okay to me.
You might want to give the variables more speaking names (e.g. nakid_root_dir, nakid_relative_webroot and so on.)
Remember when converting \ to / in path names: Whenever you match another directory name to one of those settings, you need to str_replace("\\","/"...) in those too.
I don't understand what you aim at with $get_dirnakid_2, though. Why will you screw up my path if I install your application in a directory that happens to be named /etc/includes/php/nakid?
Anyway, you should make those settings user overwritable as well. Sometimes, the user may want to set different settings from what you get from DOCUMENT_ROOT and consorts.
I don't fully understand what you try to get, but maybe getcwd() is what you look for:
http://www.php.net/manual/en/function.getcwd.php
Related
My copy code doesnt work for some reason. Tried several things.
this is the code that I am trying to use
$fb_foto_url = $userData['picture']['data']['url'];
$plaats = '/assets/images/profielfotos/fiel.jpg';
copy($fb_foto_url, $plaats);
The $userData['picture']['data']['url']is getting filled with this for example: https://lookaside.facebook.com/platform/profilepic/?asid=113831052838678&height=200&width=200&ext=1527931138&hash=AeSlklMNX6l4Uanh
I need that to get stored in on the server. But it isn't working for some reason. I am doing something wrong but can't figure out what.
If someone can help me with this code, would be nice.
Try this:
file_put_contents($plaats,file_get_contents($fb_foto_url));
PHPs copy function expects path's, not URL's.
A (server-) path is a directory name on the machine the PHP code is executed on.
An URL is a virtual name that may or may not point to such a physical path or is resolved dynamically.
Example:
The server path to a websites images might be /var/www/example.org/assets/images/, while the URL is http://example.org/assets/images/.
http://php.net/manual/en/function.copy.php
I'm currently building a simple MVC framework and I've hit a bit of a road block in terms of breaking the URL down on a localhost but also having it work on a live production server as well.
So basically, my localhost URL is:
localhost/project/public/controller/action
The live version would be:
www.example.com/controller/action
My initial thought was to just use $_SERVER['REQUEST_URI'] which will work perfectly on a live server but on my localhost it returns:
/project/public/controller/action
What I need is:
controller/action
I've had a search around and the only answer I could find was to set up a virtual host which I don't really want to do - this code will be shared between people who may or may not know how to set that up so I want to avoid it if possible.
EDIT: For the record - this is the answer I found - How to get the same $_SERVER['REQUEST_URI'] on both localhost and live server
I also can't remove /project/public/ because this folder structure won't always be the same.
So I basically need to get the path up until the public/ part but I can't even use that because the public folder may be called something else.
I know this must be possible because frameworks such as Laravel do it but even looking at the source for that - I can't quite figure it out.
Thanks for any help.
EDIT: Possible Answer
It's odd how often you have a brainwave as soon as you post something...
I've had the thought that I can just run basename(DIR) at my entry point which will give me the folder's name regardless of what it is. I can then use that to remove everything before (in including) the first instance of that folder.
I'll try this out but if there are more elegant solutions out there, I'd still like to hear them.
I also can't remove /project/public/ because this folder structure won't always be the same.
But i assume, you'll always have controller and action parts? If yes, then do this:
$uriParts = explode('/', $_SERVER['REQUEST_URI']);
$count = count($uriParts);
$controller = isset($uriParts[$count - 2]) ? $uriParts[$count - 2] : null;
$action = isset($uriParts[$count - 1]) ? $uriParts[$count - 1] : null;
Try this to get ending string from your REQUEST_URI which isn't part of the server path:
substr($_SERVER['REQUEST_URI'], strlen(dirname($_SERVER['SCRIPT_NAME'])));
I'm working on converting a website. It involved standardizing the directory structure of images and media files. I'm parsing path information from various tags, standardizing them, checking to see if the media exists in the new standardized location, and putting it there if it doesn't. I'm using string manipulation to do so.
This is a little open-ended, but is there a class, tool, or concept out there I can use to save myself some headaches? For instance, I'm running into problems where, say, a page in a sudirectory (website.com/subdir/dir/page.php) has relative image paths (../images/image.png), or other kinds of things like this. It's not like there's one overarching problem, but just a lot of little things that add up.
When I think I've got my script covering most cases, then I get errors like Could not find file at export/standardized_folder/proper_image_folderimage.png where it should be export/standardized_folder/proper_image_folder/image.png. It's kind of driving me mad, doing string parsing and checks to make sure that directory separators are in the proper places.
I feel like I'm putting too much work into making a one-off import script very robust. Perhaps someone's already untangled this mess in a re-useable way, one which I can take advantage of?
Post Script: So here's a more in-depth scoop. I write my script that parses one "type" of page and pulls content from the same of its kind. Then I turn my script to parse another type of page, get all knids of errors, and learn that all my assumptions about how paths are referenced must be thrown out the window. Wash, rinse, repeat.
So I'm looking at doing some major re-factoring of my script, throwing out all assumptions, and checking, re-checking, and double-checking path information. Since I'm really trying to build a robust path building script, hopefully I can avoid re-inventing the wheel. Is there a wheel out there?
If your problems have their root in resolving the relative links from a document and resolve to an absolute one (which should be half the job to map the linked images paths onto the file-system), I normally use Net_URL2 from pear. It's a simple class that just does the job.
To install, as root just call
# pear install channel://pear.php.net/Net_URL2-0.3.1
Even if it's a beta package, it's really stable.
A little example, let's say there is an array with all the images srcs in question and there is a base-URL for the document:
require_once('Net/URL2.php');
$baseUrl = 'http://www.example.com/test/images.html';
$docSrcs = array(...);
$baseUrl = new Net_URL2($baseUrl);
foreach($docSrcs as $href)
{
$url = $baseUrl->resolve($href);
echo ' * ', $href, ' -> ', $url->getURL(), "\n";
// or
echo " $href -> $url\n"; # Net_URL2 supports string context
}
This will convert any relative links into absolute ones based on your base URL. The base URL is first of all the documents address. The document can override it by specifying another one with the base elementDocs. So you could look that up with the HTML parser you're already using (as well as the src and href values).
Net_URL2 reflects the current RFC 3986 to do the URL resolving.
Another thing that might be handy for your URL handling is the getNormalizedURL function. It does remove some potential error-cases like needless dot segments etc. which is useful if you need to compare one URL with another one and naturally for mapping the URL to a path then:
foreach($docSrcs as $href)
{
$url = $baseUrl->resolve($href);
$url = $url->getNormalizedURL();
echo " $href -> $url\n";
}
So as you can resolve all URLs to absolute ones and you get them normalized, you can decide whether or not they are in question for your site, as long as the url is still a Net_URL2 instance, you can use one of the many functions to do that:
$host = strtolower($url->getHost());
if (in_array($host, array('example.com', 'www.example.com'))
{
# URL is on my server, process it further
}
Left is the concrete path to the file in the URL:
$path = $url->getPath();
That path, considering you're comparing against a UNIX file-system, should be easy to prefix with a concrete base directory:
$filesystemImagePath = '/var/www/site-new/images';
$newPath = $filesystemImagePath . $path;
if (is_file($newPath))
{
# new image already exists.
}
If you've got problems to combine the base path with the image path, the image path will always have a slash at the beginning.
Hope this helps.
Truepath() to the rescue!
No, you shouldn't use realpath() (see why).
I have a script that displays images based on certain conditions. When none of the conditions are met, I want to randomly display one of the standard (backup) images. Those other images are on a remote server. I have read that you can't read a directory on a remote server, which makes sense.
Is my best bet to place a file into the remote server's image directory that outputs all of the image file names so I can parse it with the other server? Is there an easier way?
I prefer not to use FTP (http://php.net/manual/en/book.ftp.php).
What are my options for basically just getting the names of the images in that folder?
Thanks,
Ryan
UPDATE:
#mario's answer is lightweight and works like a charm. It is exactly the solution I thought I wanted, but after thinking about it some more, and reading that even #mario would do it differently, I decided to go with #bensiu's answer, because to me, control and security are more important than convenience. With #mario's method, it's very hard to know if the data you're getting is any good (lack of control) and you're exposing your directory / some server information (security). #bensiu's suggestion involves a second file (inconvenience), but provides the control and security I'm ultimately deciding to go with!
Thank you both!
-Ryan
I would prefer an exact and dedicated handler script like #bensiu pointed out.
But an alternative would be to read out a directory listing. A simple Apache generated mod_index listing would be sufficient for:
$html = file_get_contents("http://example.com/images/");
preg_match_all('/<a href="([-\w\d.]+\.(jpeg|png|gif))"/', $html, $uu);
$files = $uu[1];
I hope you at least have access to remote server...
You can place there script "A" that will do the job locally, return list of images in preffered format ( raw text, JSON, XML... ), and this script will be remotly called by curl form your server....
It also wise to make sure that when you call script "A" you at least passing some secret key to prevent unathorised access (not perfect solution but could be enought)
if you have PHP5 and the HTTP stream wrapper enabled on your server, it's very easy and simple to copy it to a local file:
copy('http://somedomain.com/file.jpeg', '/tmp/file.jpeg');
ome hosts disable copy() function then you can make your own -
<?php
function copyemz($file1,$file2){
$contentx =#file_get_contents($file1);
$openedfile = fopen($file2, "w");
fwrite($openedfile, $contentx);
fclose($openedfile);
if ($contentx === FALSE) {
$status=false;
}else $status=true;
return $status;
}
?>
I'm not a PHP developer, but I'm currently hacking on an internal tool so my team can take advantage of its goodness. There's an index file that looks like so:
require( ($loader_path = "../../loaderapi/") . "loader.php" );
Used like this, $loader_path will retain its value within the loader.php file.
However, we want to access this API from our team's server like so:
require( ($loader_path = "http://remoteservername/loaderapi/") . "loader.php" );
In this case the $loader_path variable doesn't retain its value. I'm guessing it has something to do with it being a full blown URL, but I might be wrong. Any idea on how I can make this work, or why I can't do it this way?
If your accessing a PHP script over HTTP, only the output of that script is returned. So your script will try to interpret the output of that remote PHP script and not its source.
If there is a connection over the file system, you may want to try file://remoteservername/loaderapi/loader.php instead.
NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO!
Remote file inclusion is a BAD idea, probably one of the biggest security flaws you can open up. Even for an internal tool this is not acceptable even if only purely for contributing bad habits.
PHP by default disables this behavior, and there is a broad push to have the ability to perform an include on a URL completely stripped from PHP (as there is no compelling reason to have this ability).
If you want to load shared resources, go through a shared file system drive (as in, don't use http, ftp, anything but file://) or better yet distribute copies of loader.php through a version control system. Loading from a single file resource opens you up to problems in the future of say a new dev overwriting loader.php and breaking everyone else's code.
There shouldn't be any real difference between the two; what you're doing is defining $loader_path, concatenating the loader.php, and passing that to require.
HOWEVER: you're defining the variable within the scope of a require, which will halt processing of the script of require fails.
Try replacing 'require' with 'include' and see if it retains the variable.
Also, note that if you are running your PHP server on a windows machine, and the php version is less than 4.3.0, neither 'require' nor 'include' can handle remote files : http://us.php.net/manual/en/function.include.php
Also, as noted before, if the .php lives on a remote server that parses php, you will not get code, but the result of the remote server processing the code. You'll either have to serve it up as a .txt file, or write php that, when processed, outputs valid php.
Have you tried splitting it into two lines:
$loader_path = "http://remoteservername/loaderapi/";
require( $loader_path . "loader.php" );
It's easier to read this way as well.
Simplify the code reading by simply putting everything on 3 lines:
$loader_path = "http://remoteservername/loaderapi/";
$page = "loader.php";
require($loader_path . $page );
Much clearer and it works.
why not just put it above the require statement? would make it easier to read too.
<?php
$loader_path = "../../folderName/"
require($loader_path . "filename")
?>