Jump to content

Altering percieved resource path


TechnoDiver
 Share

Recommended Posts

Hi Phreaks, weird question. Difficult one to explain and I was and still am clueless on what to research if it's even possible. I even had difficulty with the title of this post.

If one has a simple file setup like this ->

root dir

|-page.php

|-index.php

and decided to alter it to the following:

root dir

|-pages/page.php

|-index.php

Than that developer would have to add '../' a few places where they had require(), include(), scripts, styles etc. and this would lead to even more issues if page.php shared resources with index.php.

So my question is, is there a way to, instead of changing all the other paths to resources, is it possible to make pages/page.php appear as if it's still in the root directory to the other resources?

To rephrase that - even though page.php is now one level deeper than it use to be, is there a technique that makes it still appear to be in the root directory to all the resources it calls? Like assign it a pseudo-location or something to where any resource that connects to it does so as if it's still located in the root directory?

Edited by TechnoDiver
Link to comment
Share on other sites

You have a problem with file paths and somehow making one file appear to be in another place is the opposite of a solution. Consider that someday you, or maybe someone else, would look at that code and wonder how the hell it seems to be including the correct file when the file path is clearly wrong.

1. If you need to move the file then that sucks. Move the file and get it over with. IDEs can often help with rename operations, otherwise it's real simple to do a quick global search for "page.php" and update the paths you find; unless you have hundreds of files, that should take only a minute or two.
2. If you do have a lot of references to change then that hints at an underlying problem in how you use files for reusable code. Give it a few minutes of thought to see if maybe there is a better way of arranging your code or whatever so that it's accessible in a way that makes more sense.
3. Don't use relative paths. Use an absolute path based on the DOCUMENT_ROOT, as in

include $_SERVER["DOCUMENT_ROOT"] . "/pages/page.php";

 

  • Thanks 1
Link to comment
Share on other sites

5 hours ago, requinix said:

You have a problem with file paths and somehow making one file appear to be in another place is the opposite of a solution. Consider that someday you, or maybe someone else, would look at that code and wonder how the hell it seems to be including the correct file when the file path is clearly wrong.

No problem, per se. I don't need to move it. It would be totally for organizational purposes. I'm using absolutes, as well. This issue I was trying to circumvent is that page.php and index.php share some resources (head.php, footer.php etc.) and even though it's easy enough to sort that out there's the stylesheets that are linked to from head.php that get messed up. 

As I was typing this last night I realized that absolute paths are likely the solution. Still having trouble with the stylesheets though.

So yea, I was looking for something that in retrospect seems kind of hacky. Thought there may have been a technique or method that could pseudo-reference a resource location.

But, like I said, the file doesn't need to be moved, it would be for purely organizational/aesthetic purposes.

Thanks for your reply

Link to comment
Share on other sites

The "real" problem is that you have no Architecture to your site. Having a direct correlation of URLS to file paths is a very restrictive and low level design. By designing using a "Front Controller" or "MVC" pattern with a single point of entry you could move files anywhere you want without affecting the URLS. Optimally, all your files should be above the root save for the index.php and your assets such as images, JS and CSS.

It may be above your current skill level but it is well worth learning.

Link to comment
Share on other sites

4 hours ago, ginerjm said:

Absolute paths that are driven by some static starting point such as DOCUMENT_ROOT as Requinix pointed out.

Yea, I'm using absolute paths, for the most part. The issue that I'm trying to resolve is with the <link> elements in head.php.for

For all includes I was using absolutes except in the link and script elements I was still using relatives.

I have a $root variable using DOC_ROOT that's in the ini file at the top of each page.

Sample usage is thus ->

Quote

<?php require_once($root.'/newsnet/includes/head.php'); ?>

The problem I'm having is using it in the link element. It sounds so stupid and basic but I can't get that variable to get picked up for the css and scripts. 2 ways I've tried are ->

<link rel="stylesheet" type="text/css" href="<?php echo $root.'/css/actors.css';?>">
<link rel="stylesheet" type="text/css" href="{$root}/css/gallery.css">

Neither work. Do I have to put the entire absolute path here each time or is there a special syntax that I'm being stupid and overlooking/forgetting about??

Link to comment
Share on other sites

I hate it when people embed php tags into their html code.  Learn to write without having to do that.  (just for grins - I use exactly one set of php tags in my entire scripts all the time)

As for example 1 - should have worked I think.  #2 tho is not gonna work since it obviously is not in php mode since there is no echo and therefore the variable won't be interpreted.   Have you examined your web page when it loads to see how it looks onscreen?

  • Like 1
Link to comment
Share on other sites

File paths and URLs are not always the same thing. Look at your browser's address bar right now: does it say?

https://forums.phpfreaks.com/var/www/forums.phpfreaks.com/index.php?controller=idontknow&action=something&whateverelse&id=313889&name=altering-percieved-resource-path

 

If your $root is also the root of the website then there's a really easy way to get an absolute path: start with a slash. That's it. / in the URL will correspond to the $root.

<link rel="stylesheet" type="text/css" href="/css/actors.css">
<link rel="stylesheet" type="text/css" href="/css/gallery.css">

 

  • Like 1
Link to comment
Share on other sites

15 minutes ago, requinix said:

If your $root is also the root of the website then there's a really easy way to get an absolute path: start with a slash. That's it. / in the URL will correspond to the $root.

Yea, I'm a bozo sometimes, man. I totally knew that and was overthinking it. I'm laughing at myself right now. Thanks

Link to comment
Share on other sites

1 hour ago, benanamen said:

It may be above your current skill level but it is well worth learning.

Yea, I'm always willing to learn though. The project I post on here mostly about literally started with 2 files and expanded into hundreds over the past year. I hadn't even owned a computer in 5 years until I bought this laptop last year specifically to try to make this project. Pretty much had to completely relearn HTML, CSS, JS and learn from scratch AJAX/JSON, MySql, PHP, GIT, OOP, working with APIs etc, it's been quite the journey. I have no background nor training in webdev, it's totally a self-taught project, in which this forum has been invaluable.

Saying all that, I wouldn't even know where to start in the direction you're speaking of. Are you referring to frameworks like Laravel?

  • Like 1
Link to comment
Share on other sites

This is a common area of confusion.  

Anything having to do with php and files (include/require/fopen, etc) wants file system paths. (OS Filesystem)

Anything having to do with web resources (images, css, javascript) wants a url. Urls only exist in webspace.  (Webspace/HTTP 2.0 Serving).

As the front controller is now a popular design pattern for web apps and frameworks, you will come to find that it is frequently the case, that the only PHP script that would be under the webroot, would be the front controller script.  All requests are thus, routed through the front controller, using a router.   All the classes and other php scripts will be in directories that are not visible in any way from webspace.  This is far superior in numerous ways, than a system that has entry points from scripts that have been mapped into webspace.   I only bring this up because if you think about it for a minute, it should reinforce your understanding that PHP's functions require a filesystem path and not a url.  PHP can load scripts in any directory on your file server that the PHP process has operating system level access to.

Things that are not related to php code, as mentioned above, that in general are referenced in your html markup, are things in webspace.  Each can be accessed via a url.  

Both webspace/url's and filesystems can have relative paths, so this can lead to confusion.  A relative filesystem path is typically relative to the "current working directory" of the process that is running.  This can easily get confusing when you are executing scripts that one or 2 levels deep in a hierarchy.  For this reason, some technique which establishes the filesystem project root is helpful.  That could be the document root, or as is more common these days, a variable or constant established through a bootloader or init script that references either the __FILE__ or __DIR__ magic constants. 

Using this technique is equivalent to, from a file system perspective, establishing something like the document root for your php code.  At that point you can have simple helper functions that can concat project relative paths to it, to always have a fully qualified filesystem path.

As an example, here is a simplified version of a directory path you will find using one of a number of the more popular PHP frameworks.  

var/
├─ www/
│  ├─ my_website/
│  │  ├─ config/
│  │  │  ├─ init.php
│  │  ├─ public/
│  │  │  ├─ css/
│  │  │  │  ├─ style.css
│  │  │  ├─ images/
│  │  │  ├─ js/
│  │  │  ├─ index.php
│  │  ├─ src/
│  │  │  ├─ pageA.php
│  │  │  ├─ pageB.php
│  │  ├─ vendor/



In this case, the webroot of the site will be mapped to the filesystem /var/www/my_website/public

So the css file in markup can be referenced as:  https://www.mywebsite.com/css/style.css.  However, in your markup it would be completely safe and reasonable to reference it with the relative path "/css/style.css"

What about file system paths for a PHP require of pageA.php?  Keep in mind, that only the public directory is visible to webspace.  there is no way to reach any file using a url in the src or vendor directories.

Let's assume that at some point in the .../public/index.php there is code that is trying to require_once("pageA.php")

You could attempt to use relative paths, based on the knowledge of where the public directory exists relative to the src directory, but this can get very convoluted once you have more complicated file system trees.  It would be convenient to always use the relative path of the src script. In the case it would be simply "/src/pageA.php".

A solution in index.php could be a function that always returns the path to the project directory (my_website).  That would work great in index.php as a front controller, because every request goes through it, so if that variable gets initialized it can be safely used in all includes.  

In your case, you don't have a front controller, so this isn't as helpful.  There is however, a common pattern that has been used to do this, and that is to make sure that any executing script (script that can be directly referenced in webspace)  requires a config, bootstrap or setup script in the root of your project.  This isn't perfect, because the filesystem path to this script will vary depending on the directory structure you have, but at worst you need a relative file system path to it.  Let's assume in this example this would be .../config/init.php

In init.php you have this variable defined:

<?php

$PROJECT_ROOT = substr(@realpath(dirname(__FILE__)),0,  -1 * strlen('/config'));

// The only hardwired fact here, is that the init.php script is in the /config directory.  We need to strip that off the path to get back to the root.  
//If it was further nested from the project root, the '/config' constant would need to be changed accordingly to where it exists.  
//Keep in mind there would only be one of these files in the project, and typically it might also have other global configuration variables like database credentials.  

So long as you include the .../config/init.php script, you will be able to use the $PROJECT_ROOT, and append your relative file system paths to it to include or reference other scripts.  All you need to know is the location of those scripts relative to your project (my_website).  

So in index.php, code like this could be used to reliably reference pageA for inclusion, simply knowing that relative to the project, it exists in the src directory.  Furthermore pageA.php could reference pageB.php reliably.

 

// In public/index.php

require_once("../config/init.php");

// Sometime later, we need pageA.php

require_once($PROJECT_ROOT . '/src/pageA.php');

// In pageA.php,  pageA.php needs pageB.php
require_once($PROJECT_ROOT . '/src/pageB.php');

 

Since in your case, again you don't have a front controller, you just need to make sure that any scripts that get directly executed by the web server via a url, include the "config/init.php" script in relative fashion.  You probably already have a configuration script like this in your project, that everything must include, and if so, that would be a good candidate for adding the $PROJECT_ROOT to.

Hope this helps.  As most people are now using composer, with component libraries, and class autoloading using PSR-0 or PSR-4 standards with classes and namespaces, this already solves a lot of file inclusion problems for a project, and the more you can move your project towards an MVC pattern, the easier it will be to extend, enhance and test.  

If you don't understand composer, namespaces, autoloading etc., these would be excellent growth areas for you, allowing you to evolve your project towards something more sophisticated and professional.

 

 

 

  • Great Answer 1
Link to comment
Share on other sites

6 hours ago, TechnoDiver said:

I wouldn't even know where to start in the direction you're speaking of. Are you referring to frameworks like Laravel?

I am not suggesting you go to a Framework although they are structured the way I mentioned. Check out this free Laracast video series on PHP. It is the only video tutorial I have seen that I would recommend to anyone. It will get you going in the right direction. Watch each one even if you understand it already.

The PHP Practitioner
https://laracasts.com/series/php-for-beginners

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.