7

I have a file located in my CakePHP root folder placed under a folder named cron. Path is:

c:/wamp/www/project/cron/daily.php

This file requires another file placed inside vendor folder of cake structure, like this:

require("/../vendors/phpMailer/class.phpmailer.php");

And i run this daily.php from task scheduler. This is the scenario in my development site.(Windows system). It works fine as expected. When i migrated the project to Ubuntu(production site), the require statement started causing issues; it cant find the required file. I made a small change there, like this:

require("../vendors/phpMailer/class.phpmailer.php"); <= removed the preceding slash

And it worked. So my doubt is, is there a difference in how parent directory notation work in widows and Linux? If so, how can i overcome this? Its not feasible to remove a slash every time I move the project from my development site(windows) to production site (Linux).


I tried this:

 require("./../vendors/phpMailer/class.phpmailer.php");

It worked in linux. But gave "no such file directory" error in windows. It seems windows works only with:

 require("/../vendors/phpMailer/class.phpmailer.php");

Solution

From @TWCrap's help problem was solved as follows:

require(dirname(__FILE__)."/../vendors/phpMailer/class.phpmailer.php");

It works in both windows and linux(* tears of joy *). But in windows it produces path as:

C:\wamp\www\project\cron/../vendors/phpMailer/class.phpmailer.php

This path looks ugly and i hope it wont cause probs in future!

-Thanks guys!

Ivin
  • 4,435
  • 8
  • 46
  • 65
  • the / in the begining in linux meens to Root directory (as if you wrote C:/ in windows). anyway I don't think you need the / in the begining for windows too. no ?! – Oussama Jilal Sep 07 '12 at 10:57
  • Use an an absolute path? – Wayne Whitty Sep 07 '12 at 10:57
  • FYI, `/..` is a nonsensical root path on any sane OS. What you are saying is "directory above the root directory", which obviously does not exist. This will effectively be treated as the root. I suspect that what you meant is `./..` which is, incidentally, the most efficient way to specify a path for `include`/`require` because it will prevent PHP from searching through the `include_path` and look directly at the exact location you specified. – DaveRandom Sep 07 '12 at 11:02
  • @Yazmat it should work without / at the beginning in windows. (../) refers to parent dir in windows. But somehow here it behaves weird. – Ivin Sep 07 '12 at 11:24
  • `dirname(__FILE__) == __DIR__`. Or am I wrong. – DerpyNerd Apr 18 '17 at 11:37
  • @Oussama - In this context, '/' does not mean root directory. It is used to go back to a subdirectory. So the context is very important. – Nguai al Dec 12 '19 at 08:01
  • @DaveRandom - In this context, '/' is not used as a root directory. Please read a note I sent to Oussama. Context is very important. – Nguai al Dec 12 '19 at 08:03
  • @Yazmat - You must have it. '/' is used as a closure of current directory. In this context, '/' is not used as a root directory. – Nguai al Dec 12 '19 at 08:05
  • @DerpyNerd - They mean the same. – Nguai al Dec 12 '19 at 08:07
  • I am surprised that require("./../vendors/phpMailer/class.phpmailer.php"); didn't work for Windows. If you know the answer why it didn't work with Windows, please explain. – Nguai al Dec 12 '19 at 08:17

3 Answers3

6

AS i remember, when you put 1 dot infront of the line, you start at the directory you are. So then the line must look like this:

require("./../vendors/phpMailer/class.phpmailer.php");

And that should work at windows and linux....

Mathlight
  • 6,436
  • 17
  • 62
  • 107
  • @Orbb The key here is `getcwd()` – DaveRandom Sep 07 '12 at 11:29
  • @Orbb, as DaveRandom mentiod, can you use getcwd to got the current dir, and use that dir to go to somewhere else. You can make an dir path with dirname() http://php.net/manual/en/function.dirname.php – Mathlight Sep 07 '12 at 11:31
  • @Orbb, you can also get the current direcotry by using: `dirname(__FILE__)` – Mathlight Sep 07 '12 at 12:13
  • @TWCrap In windows its ver 5.3.8 and in linux its 5.3.2-1ubuntu4.17 – Ivin Sep 07 '12 at 12:20
  • @TWCrap yes dirname function is valid in both versions. But i cant figure out how to build path from getcwd using dirname. getcwd gives "/var/www/project/cron/" in linux and "C:\" in windows. Not the common place, right? – Ivin Sep 07 '12 at 12:27
  • 1
    Right, but if i remember right, can you use `dirname(__FILE__)` to get the dir path of the file where it's called from. And i thenk that you can use that to get to the right dir, am i right??? – Mathlight Sep 07 '12 at 12:30
  • No Problem ;-) I'm glad that i could help You Don't forget to mark the answer ;-) – Mathlight Sep 07 '12 at 12:47
  • @Orbb - '__DIR__ 'is another and a common way. – Nguai al Dec 12 '19 at 08:19
  • @phoenix - use __DIR__ – Nguai al Dec 12 '19 at 08:19
2

Do not use absolute paths if you really do not need so. It's safer and better to correctly set include_path so in case of move you just need to adjust one setting instead of digging thru whole project and all its files.

So my doubt is, is there a difference in how parent directory notation work in widows and Linux?

Paths starting with / (i.e. /foo/bar) are absolute paths as starting / indicates root folder. On Windows you got drive letter there.

I also suggest using require_once to avoid duplicated requires (which is OK if you mix HTML with code, but "spaghetti code" is not recommended anyway), but may cause problems with code

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
  • 1
    `And these differences are not transparently handled by PHP` - yes, they are, in fact they are transparently handled by Windows itself. Windows (not just PHP) will allow you to use `/` as a path separator just about everywhere apart from cmd.exe. It will also treat a path beginning with `/` as starting from the route of the currently selected drive. If you write all the paths in your PHP scripts as if they were *nix paths, they will work on Windows. – DaveRandom Sep 07 '12 at 11:11
  • Yes, I know "/" works on Windows, I was (not clearly) referring to lack root drive mapping. If I am wrong on that, then thanks for correcting. – Marcin Orlowski Sep 07 '12 at 11:21
0

The problem is that, at least on a UNIX system, when you start with a preceding slash on a file path you start at the root.

You should either write ./../* or just ../ ond both systems. It should work both.

Louis Huppenbauer
  • 3,719
  • 1
  • 18
  • 24