How can I obtain the full path of a nextcloud file - php

I started writing an app for nextcloud. For my app to work, I need to be able to pass the complete path of files located in the file directory of the logged in user to a CLI command.
I know that the base path of the file directory is defined in config.php; for example, it is 'var/www/html/nextcloud' or 'var/www/nextcloud'.
I have found a couple of functions that allow me to get the relative path, e.g.
\OC\Files\Filesystem::getFileInfo($path)
and
\OC\Files\Filesystem::getInternalPath($path)
Unfortunately, I couldn't find a function that either directly returns the full path of a file or at least the base path from config.php.
Do any of you have a tip for me?

Thanks for your help, misorude!
In the meantime I have found a solution:
in Nextcloud there is a class \OC\Config which has the method OC\Config::getValue($key, $default=null)
(see https://docs.nextcloud.com/server/latest/developer_manual/api/OC/Config.html)
The difficulty I had with this was that the initialization of a class instance expects the specification of a path, namely the path where the config.php file is located.
This irritated me at first, because it seems you are chasing your own tail here.
Then I tried specifying only the relative path to the Nextcloud installation, and that worked immediately. So to make it short, here's the code you need:
$config = new \OC\Config('config/');
$base_path = $config->getValue('datadirectory')
datadirectory is the key in the array defined in config.php that contains the base directory.
$basepath now contains a path like /var/www/html/nextcloud/data.
I hope this helps someone.
Best regards,
Tom

Related

PHP Polymorphic Root Requires

I have a directory/file tree as follows:
index.php
/frame/main_class.php
/frame/func/function_1.php
/frame/func/function_1.php
/cfg/config.php
//index.php
require('frame/main_class.php');
new main_class;
//frame/main_class.php
class main_class{
public function __construct(){
require('func/function_1.php');
require('func/function_2.php');
require('cfg/config.php');
}
}
The weird part is that it works. Maybe it is late and I am having a dumb-moment, but shouldn't "require('cfg/config');" be written "require('../cfg/config.php');" ?
And if it is using the root of index.php, then "require('func/function_1.php');" shouldn't work, right?
I have quadruple checked the remote server thinking that maybe there was a stray file or two... there isn't.
How can the two require statements have a different base path.....?
Does anyone know of a code snippet that could cause this to happen? I am working with some $_SERVER variables but I don't appear to be changing any of them....!?
"Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include will finally check in the calling script's own directory and the current working directory before failing." Explicitly saying include dirname(__FILE__) . '/path/to/file.php';avoids this confusion. – DCoder
Link to PHP Manual on "dirname".
The PHP engine will look for the requested files in the current directory, but it will also look for them in the list of paths defined in INCLUDE_PATH. If the include path lists the path from where your script is running then the given code will work. If not then it wont.
For that reason amongst others it's not a good idea to rely on the include path to resolve the path of included files. You should give the full path instead.

PHP: Cannot see upload directory

I have been struggling for a few days trying to find out how come I cannot move a file(move_uploaded_file) from temp to the directory I have setup (/img/uploads/photos).
After alot of testing and head scratching, I decided to write into CakePHP's CakeLog whatever is happening in the upload function.
Although I have physically created :/img/uploads/photos, when I use CakeLog::write('debug', 'Does directory exist?: '.json_encode(file_exists('/img/uploads/photos/'))); it logs false. Or is_dir, also returns false
Why is this happening... Can anyone help me out!
I doubt you have made a directory /img/uploads/photos/ ? It is probably inside the same dir as your other files, somewhere like /var/www/yoursite/img/uploads/photos/ or something like that.
You can use some tricks like $_SERVER{'DOCUMENT_ROOT'}, as you can see over at http://php.net/manual/en/function.file-exists.php
I don't believe you when you say you have created the /img/uploads/photos/ directory. That's an absolute path, counting from the root of the machine. It's more probable that you have created the folder in the web directory somewhere (such as /var/www/img/uploads/photos/ or /home/caboone/public_html/img/uploads/photos/).
The path /img/... means the path is relative to the disk root, i.e. it denotes the img directory in the very top level of your hard disk. I doubt that's where the directory is. Don't start the path with a / to make it relative to the file you're working in. File paths are not URLs!
Use absolute path when moving files from one directory to another.
Use dirname(__FILE__) to get the absolute current working directory, then add
the rest of the path.
Set appropriate permission to the directory, as suggested by #Alex. use chmod() and
set permission to 777 (ugo+w) [user+group+others world-writeable].

Include files from parent or other directory

I'm needing to include a file from the parent directory, and other sub-directories, into a sub-directory. I've done it before by simply using include('/rootdirectory/file.php'); but now it won't seem to work.
Just wondering how I can do this, thanks.
Here's my exact line:
include('/forums/groups.php');
It's giving me this error(the page still runs):
Warning: include(/forums/groups.php) [function.include]: failed to
open stream: No such file or directory in
C:\xampp\htdocs\forums\blog\posts.php on line
Warning: include() [function.include]: Failed opening
'/forums/groups.php' for inclusion
(include_path='.;C:\xampp\php\PEAR') in
C:\xampp\htdocs\forums\blog\posts.php on line 3
include() and its relatives take filesystem paths, not web paths relative to the document root. To get the parent directory, use ../
include('../somefilein_parent.php');
include('../../somefile_2levels_up.php');
If you begin with a /, an absolute system file path will be used:
// Full absolute path...
include('/home/username/sites/project/include/config.php');
If your server is not resolving the file from the parent directory using
include '../somefilein_parent.php'
try this (using the parent directory relative to the script):
include __DIR__ . "/../somefilein_parent.php";
Here's something I wrote with that problem in mind:
<?
function absolute_include($file)
{
/*
$file is the file url relative to the root of your site.
Yourdomain.com/folder/file.inc would be passed as
"folder/file.inc"
*/
$folder_depth = substr_count($_SERVER["PHP_SELF"] , "/");
if($folder_depth == false)
$folder_depth = 1;
include(str_repeat("../", $folder_depth - 1) . $file);
}
?>
hope it helps.
Depends on where the file you are trying to include from is located.
Example:
/rootdir/pages/file.php
/someotherDir/index.php
If you wrote the following in index.php:
include('/rootdir/pages/file.php');it would error becuase it would try to get:
/someotherDir/rootdir/pages/file.php Which of course doesn't exist...
So you would have to use include('../rootdir/pages/file.php');
In laymans terms, and practicality, I see this as an old DOS trick/thing. Whoa! What was that? DOS? Never heard of it!
".." backs you out of the current sub-directory one time to a higher folder/directory, and .. enter typed twice backs you out too 2 higher parent folders. Keep adding the ".. enter" back to back and you will soon find yourself at the top level of the directory.
As for Newbies to understand this better, consider this (in terms of the home PC or "C:\ drive" if you know what that means, rather than the web-servers/host "root directory" ). While your at it, Consider your website existing somewhere on your home PC's hard drive, buried in some folder under the C:\ drive. Lastly, you can think of it as ".." is back one directory and "/" is forward one directory/folder.
Now!
If you are using the command prompt and are within the "myDocuments" folder of your PC you must back out of that folder to get closer to the higher directory "C:\" by typing the "../".
If you wanted to access a file that is located in the widows directory while you are still in the myDocuments folder you would theoretically type ../windows; in reality of DOS command prompt you would simply type .., but I am setting you up for the web. The / redirects forward to another directory naturally.
Using "myDocuments" lets pretend that you created 2 folders within it called "PHP1" and "PHP2", in such we now have the folders:
C:\myDocuments\PHP1
C:\myDocuments\PHP2
In PHP1 you place a file called index.php. and in PHP2 folder you placed a file called Found.php. it now becomes:
C:\myDocuments\PHP1\index.php
C:\myDocuments\PHP2\found.php
Inside the
C:\myDocuments\PHP1\index.php file you would need to edit and type something like:
<?php include ('../php2/found.php')?>
The ../ is positional thus it considers your current file location "C:\myDocuments\PHP1\index.php" and is a directive telling it to back out of PHP1 directory and enter or move forward into PHP2 directory to look for the Found.php file. But does it read it? See my thoughts on trouble shooting below.
Now! suppose you have 1 folder PHP1 and a sub-folder PHP2:
C:\myDocuments\PHP1\PHP2
you would simply reference/code
<?php include('/PHP2/found.php') ?>
as PHP2 exist as a sub-directory, below or within PHP1 directory.
If the above does not work it may have something to do with access/htaccess or permission to the directory or a typo. To enhance this...getting into trouble shooting...If the "found.php" file has errors/typo's within it, it will crash upon rendering at the error, such could be the reason (require/require_once) that you are experiencing the illusion that it is not changing directories or accessing the file.
At last thought on the matter, you may need to instantiate your functions or references in order to use the included/require "whatever" by creating a new variable or object such as
$newObject = new nameobject("origianlThingy");
Remember, just because you are including/requiring something, sometimes means just that, it is included/required to run, but it might need to be recreated to make it active or access it. New will surely re-create an instance of it "if it is readable" and make it available within the current document while preserving the original. However you should reference the newly created variable $newObject in all instances....if its global.
To put this in perspective of some web host account; the web host is some whopping over sized hard-drive (like that on your PC) and your domain is nothing more than a folder they have assigned to you. Your folder is called the root. Inside that folder you can do anything you are allowed to do.
your "one of many ways" to move between directories/folders is to use the ../ however many times to back out of your current in reference to folder position you want to find.
In my drunken state I realize that I know too much to be sane, and not
enough to be insane!"
Any path beginning with a slash will be an absolute path. From the root-folder of the server and not the root-folder of your document root. You can use ../ to go into the parent directory.
You may interest in using php's inbuilt function realpath().
and passing a constant DIR
for example:
$TargetDirectory = realpath(__DIR__."/../.."); //Will take you 2 folder's back
String realpath() :: Returns canonicalized absolute pathname ..
I took inspiration from frank and I added something like this in my "settings.php" file that is then included in all pages when there is a link:
"settings.php"
$folder_depth = substr_count($_SERVER["PHP_SELF"] , "/");
$slash="";
for ($i=1;$i<=($folder_depth-2);++$i){
$slash= $slash."../";
}
in my header.php to be included in all pages:
a href= .... php echo $slash.'index.php'....
seems it works both on local and hosted environment....
(NOTE: I am an absolute beginner )
Had same issue earlier solved like this :
include('/../includes/config.php'); //note '/' appearing before '../includes/config.php'
the root directory (in PHP) is the directory of the file that is pinged. For example, I go to http://localhost/directory/to/file/index.php, the root directory will be "/dictory/to/file", since it's the one that you've made a web request for.
I can't believe none of the answers pointed to the function dirname() (available since PHP 4).
Basically, it returns the full path for the referenced object. If you use a file as a reference, the function returns the full path of the file. If the referenced object is a folder, the function will return the parent folder of that folder.
https://www.php.net/manual/en/function.dirname.php
For the current folder of the current file, use $current = dirname(__FILE__);.
For a parent folder of the current folder, simply use $parent = dirname(__DIR__);.
If your configuration file PHP.ini is set up correctly then you can use:
include($_SERVER["DOCUMENT_ROOT"]."/my_script.php");
// or
require($_SERVER["DOCUMENT_ROOT"]."/my_script.php");

OpenId library (include files are not found by script)

I have been trying to implement openid functionality into my website. I downloaded the JanRain's library.
I extracted the 'Auth' folder in my classes directory and following the example in the 'example' folder I created the try_auth.php, finish_auth.php, common.php file in the include directory.
Now when I click on the openid selector link I am presented with an error message that says 'openid.php' file not found.
This file is present in the Auth directory.
I corrected it and then I am being presented with a different error which says 'Auth/Yadis/HTTPFetcher.php' not found.
If I sit and change the require path individually in every file in the auth folder then it will take a long time.
my apps directory structure is like this
app
classes
Auth (openid library)
config
elements
includes
views
webroot
index.php
Please help me what am I doing wrong. How do I set the includepath so that all the files take their respective paths automatically.
Thanks
as the documentation states (you don't mention a version, so i am assuming you are using 2.x.x), the Auth/ directory in this package has to be in your PHP include path. there are various ways to do that: php.ini, httpd.conf/.htaccess, ini_set(), ... if you do it in your php.ini, with your apps directory being /path/to/your/app, it would look like that:
; UNIX: "/path1:/path2"
include_path = ".:/php/includes:/path/to/your/app/classes"
;
; Windows: "\path1;\path2" or "c:/path1;c:/path2"
;include_path = ".;c:/php/includes;c:/path/to/your/app/classes"
The files are there you're just not setting the path correctly.
You said this is the path it's looking for 'Auth/Yadis/HTTPFetcher.php'
You might need to add the full path, something like this:
/var/www/html/whaterver/Auth/Yadis/HTTPFetcher.php
or
/this/is/where/you/put/the/path/to/the/file/Auth/Yadis/HTTPFetcher.php
just do this command to find the base path and append it to your file path
echo `pwd`;
NOTE: those are backticks not single quotes around the pwd command
EDIT:
You just need to add this to the file that your trying to include into your script.
EXAMPLE:
your file is here: /var/www/html/index.php
and you need to include this file here: /classes/package/files.php
This file: /classes/package/files.php know where all the other files are that come in the package, so no need to edit any of these.
But you do need to edit the /var/www/html/index.php file and add something lie this:
include('/var/www/html/classes/packages/files.php');
once you have this in your script it should know where everything else is.
or as #ax has stated this looks to be a php.ini configuration
Hope this helps
You can set the include path with the set_include_path function call (http://php.net/set_include_path), if that's what you're asking...
Do a getcwd to find the directory you are in and make the appropiate chdir(s) to resolve your problem. It is a dirty solution but it should work with a minimal effort.

How do I set an absolute include path in PHP?

In HTML, I can find a file starting from the web server's root folder by beginning the filepath with "/". Like:
/images/some_image.jpg
I can put that path in any file in any subdirectory, and it will point to the right image.
With PHP, I tried something similar:
include("/includes/header.php");
...but that doesn't work.
I think that that this page is saying that I can set include_path once and after that, it will be assumed. But I don't quite get the syntax. Both examples start with a period, and it says:
Using a . in the include path allows for relative includes as it means the current directory.
Relative includes are exactly what I don't want.
How do I make sure that all my includes point to the root/includes folder? (Bonus: what if I want to place that folder outside the public directory?)
Clarification
My development files are currently being served by XAMPP/Apache. Does that affect the absolute path? (I'm not sure yet what the production server will be.)
Update
I don't know what my problem was here. The include_path thing I referenced above was exactly what I was looking for, and the syntax isn't really confusing. I just tried it and it works great.
One thing that occurs to me is that some people may have thought that "/some/path" was an "absolute path" because they assumed the OS was Linux. This server is Windows, so an absolute path would have to start with the drive name.
Anyway, problem solved! :)
What I do is put a config.php file in my root directory. This file is included by all PHP files in my project. In that config.php file, I then do the following;
define( 'ROOT_DIR', dirname(__FILE__) );
Then in all files, I know what the root of my project is and can do stuff like this
require_once( ROOT_DIR.'/include/functions.php' );
Sorry, no bonus points for getting outside of the public directory ;) This also has the unfortunate side affect that you still need a relative path for finding config.php, but it makes the rest of your includes much easier.
One strategy
I don't know if this is the best way, but it has worked for me.
$root = $_SERVER['DOCUMENT_ROOT'];
include($root."/path/to/file.php");
The include_path setting works like $PATH in unix (there is a similar setting in Windows too).It contains multiple directory names, seperated by colons (:). When you include or require a file, these directories are searched in order, until a match is found or all directories are searched.
So, to make sure that your application always includes from your path if the file exists there, simply put your include dir first in the list of directories.
ini_set("include_path", "/your_include_path:".ini_get("include_path"));
This way, your include directory is searched first, and then the original search path (by default the current directory, and then PEAR). If you have no problem modifying include_path, then this is the solution for you.
There is nothing in include/require that prohibits you from using absolute an path.
so your example
include('/includes/header.php');
should work just fine. Assuming the path and file are corect and have the correct permissions set.
(and thereby allow you to include whatever file you like, in- or outside your document root)
This behaviour is however considered to be a possible security risk. Therefore, the system administrator can set the open_basedir directive.
This directive configures where you can include/require your files from and it might just be your problem.
Some control panels (plesk for example) set this directive to be the same as the document root by default.
as for the '.' syntax:
/home/username/public_html <- absolute path
public_html <- relative path
./public_html <- same as the path above
../username/public_html <- another relative path
However, I usually use a slightly different option:
require_once(__DIR__ . '/Factories/ViewFactory.php');
With this edition, you specify an absolute path, relative to the file that contains the require_once() statement.
Another option is to create a file in the $_SERVER['DOCUMENT_ROOT'] directory with the definition of your absolute path.
For example, if your $_SERVER['DOCUMENT_ROOT'] directory is
C:\wamp\www\
create a file (i.e. my_paths.php) containing this
<?php if(!defined('MY_ABS_PATH')) define('MY_ABS_PATH',$_SERVER['DOCUMENT_ROOT'].'MyProyect/')
Now you only need to include in every file inside your MyProyect folder this file (my_paths.php), so you can user MY_ABS_PATH as an absolute path for MyProject.
Not directly answering your question but something to remember:
When using includes with allow_url_include on in your ini beware that, when accessing sessions from included files, if from a script you include one file using an absolute file reference and then include a second file from on your local server using a url file reference that they have different variable scope and the same session will not be seen from both included files. The original session won't be seen from the url included file.
from: http://us2.php.net/manual/en/function.include.php#84052
hey all...i had a similar problem with my cms system.
i needed a hard path for some security aspects.
think the best way is like rob wrote. for quick an dirty coding
think this works also..:-)
<?php
$path = getcwd();
$myfile = "/test.inc.php";
/*
getcwd () points to:
/usr/srv/apache/htdocs/myworkingdir (as example)
echo ($path.$myfile);
would return...
/usr/srv/apache/htdocs/myworkingdir/test.inc.php
access outside your working directory is not allowed.
*/
includ_once ($path.$myfile);
//some code
?>
nice day
strtok
I follow Wordpress's example on this one. I go and define a root path, normally the document root, and then go define a bunch of other path's along with that (one for each of my class dirs. IE: database, users, html, etc). Often I will define the root path manually instead of relying on a server variable.
Example
if($_SERVER['SERVERNAME'] == "localhost")
{
define("ABS_PATH", "/path/to/upper/most/directory"); // Manual
}
else
{
define("ABS_PATH, dirname(__FILE__));
// This defines the path as the directory of the containing file, normally a config.php
}
// define other paths...
include(ABS_PATH."/mystuff.php");
Thanks - this is one of 2 links that com up if you google for php apache windows absolute path.
As a newbie to intermed PHP developer I didnt understand why absolute paths on apache windopws systems would be c:\xampp\htdocs (apache document root - XAMPP default) instead of /
thus if in http//localhost/myapp/subfolder1/subfolder2/myfile.php I wanted to include a file from http//localhost/myapp
I would need to specify it as:
include("c:\xampp\htdocs\myapp\includeme.php")
or
include("../../includeme.php")
AND NOT
include("/myapp/includeme.php")
I've come up with a single line of code to set at top of my every php script as to compensate:
<?php if(!$root) for($i=count(explode("/",$_SERVER["PHP_SELF"]));$i>2;$i--) $root .= "../"; ?>
By this building $root to bee "../" steps up in hierarchy from wherever the file is placed.
Whenever I want to include with an absolut path the line will be:
<?php include($root."some/include/directory/file.php"); ?>
I don't really like it, seems as an awkward way to solve it, but it seem to work whatever system php runs on and wherever the file is placed, making it system independent.
To reach files outside the web directory add some more ../ after $root, e.g. $root."../external/file.txt".

Categories