Connecting Tech Pros Worldwide Forums | Help | Site Map

SplFileInfo issues

johannes.heinen@googlemail.com
Guest
 
Posts: n/a
#1: Nov 1 '08
Hello,

i recently fell into trouble while extending a few Spl-Classes
(SplFileInfo, RecursiveDirectoryIterator ...) for implementing a so
called "filemanager".

In short: You specify a filebase-root-directory (e.g. /home/www/cms/
public/filebase/ =note the slash "/" at the end of my path). My
filemanger-Class creates FileMangerFile-Instances (extending
SplFileInfo-Objects) for each directory and file under the above shown
path. It also creates an FileManagerFile-Instance of the "root-path"
to the filemanger-directory itself.

The Problem:
new SplFileInfo(/home/www/cms/public/filebase/)->getFilename() returns
empty value
new SplFileInfo(/home/www/cms/public/filebase)->getFilename() returns
"filebase"

SplFileInfo::getBasename() seems not to be documented nor implemented
yet (???), i have not found ressources for that. I would expect that
getBasename() "automagickally" delivers the filename of the
SplFileInfo-Object, beside beeing a folder, a file, a symlink ... An
Example:
getBaseName(/home/hans/wurst/käse.jpg")=>käse.jpg
getBaseName(/home/hans/wurst/) =wurst
getBaseName(/home/hans/wurst)=wurst

But it doesn't, obviously SplFileInfo::getBaseName() implements the
same logic as SplFileInfo::getFileName()

This is a real Problem, because internally i calculate absolute and
relative paths for using in internal file-operations (rmdir("/home/www/
cms/public..."), mkdir etc) but also for using in my view-layer (<img
src="/filebase/folder/image.jpg").

To calculate a relative pathname, i simply make a preg_replace with
$_SERVER[DOCUMENT_ROOT] on SplFileInfo::getPathName()

BUT: This will not work if you dont have a strict "trailing-slash"-
convention, or on the other hand i had to implement much "magic
trailing slash logic overhead" - and i simply want to avoid this.

So, my question is not to solve a special logic or syntactic question,
i rather want to inquire if there are some "best-practice-workflows"
to parallelly deal with internal/external, relative/absolute filenames
and how to deal with trailing slashes?

Thanks in advance,
der Johannes

(didn't get the point? Thats not your problem but a result of my bad
englisch ... sorry :((

Thomas Mlynarczyk
Guest
 
Posts: n/a
#2: Nov 1 '08

re: SplFileInfo issues


johannes.heinen@googlemail.com schrieb:

[I have]
Quote:
new SplFileInfo(/home/www/cms/public/filebase/)->getFilename() returns
empty value
new SplFileInfo(/home/www/cms/public/filebase)->getFilename() returns
"filebase"
[I want]
Quote:
getBaseName(/home/hans/wurst/käse.jpg")=>käse.jpg
getBaseName(/home/hans/wurst/) =wurst
getBaseName(/home/hans/wurst)=wurst
If you refer to a file, you want just the filename without the path
(käse.jpg). And that part works. If you refer to a folder, you want its
name, regardless of the presence/absence of a trailing slash. And you
already get the desired behaviour without the trailing slash. Well, in
that case, the solution is to remove any trailing slash:

$file = rtrim( '/home/www/cms/public/filebase/', '/' );
new SplFileInfo( $file )->getFilename()

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux ā avoir tort qu'ils ont raison!
(Coluche)
johannes.heinen@googlemail.com
Guest
 
Posts: n/a
#3: Nov 1 '08

re: SplFileInfo issues


On Nov 1, 2:20*pm, Thomas Mlynarczyk <tho...@mlynarczyk-webdesign.de>
wrote:
Quote:
If you refer to a file, you want just the filename without the path
(käse.jpg). And that part works. If you refer to a folder, you want its
name, regardless of the presence/absence of a trailing slash. And you
already get the desired behaviour without the trailing slash. Well, in
that case, the solution is to remove any trailing slash:
>
$file = rtrim( '/home/www/cms/public/filebase/', '/' );
new SplFileInfo( $file )->getFilename()
Yes, i think that's it, thank you. While writing my "essay" above the
point already went clearer - i think the main problem is that in my
whole application i did not spent enough time for organizing file- and
pathnames properly. So i came into weired issues and thought to
complicated than rather doing the job to cleanup my config-files^^.

The next step is to clean up pathnames and get rid of trailing slashes
- following your suggestion. I would like to take your rtrim solution
for getting this done, but i wonder if realpath() is able to handle
this properly and platform-independent? (I fear traps like
realpath("") =".", realpath("/") ="/" and the backslash on windows-
platforms). Do you think that there are arguments against using
realpath to filter every constructor-argument of SplFileInfo()? -
Think it may be too easy to work properly...^^

regards,
Johannes
Thomas Mlynarczyk
Guest
 
Posts: n/a
#4: Nov 1 '08

re: SplFileInfo issues


johannes.heinen@googlemail.com schrieb:
Quote:
The next step is to clean up pathnames and get rid of trailing slashes
- following your suggestion. I would like to take your rtrim solution
for getting this done, but i wonder if realpath() is able to handle
this properly and platform-independent? (I fear traps like
realpath("") =".", realpath("/") ="/" and the backslash on windows-
platforms). Do you think that there are arguments against using
realpath to filter every constructor-argument of SplFileInfo()? -
Think it may be too easy to work properly...^^
If you want to use realpath(), watch out for the following:

- determine if you are dealing with a file or a folder
- make sure the folder exists: is_dir( dirname( $file ) ), or
check the return value of realpath() accordingly
- remove any trailing slashes before calling realpath()
- don't rely on realpath() for adding/removing trailing slashes

As for removing the trailing slash in a platform-independent way:

rtrim( $file, '\/' )
or
rtrim( $file, DIRECTORY_SEPARATOR )

In your constructor, you could "clean" the filebase-root-directory like
this:

if ( !is_string( $file ) ) { throw new InvalidArgumentException; }
if ( !is_dir( $file ) ) { throw new InvalidArgumentException; }
// Take no chances with realpath() and trailing slash
$file = rtrim( realpath( rtrim( $file, '\/' ) ), '\/' );
// Append DIRECTORY_SEPARATOR if you like:
$file .= DIRECTORY_SEPARATOR;

But unless you need a canonical representation of $file, you probably
are better off without realpath(). I have written an autoloader class
using realpath(). It worked under Windows, but not under Linux -- due to
realpath()'s appending/stripping trailing slashes in its output, which
it handled differently on the two platforms. As I didn't really need it,
I removed it and now my class works on both systems.

You might also want to take a look at the glob() function:

glob( $input, GLOB_BRACE | GLOB_MARK | GLOB_ONLYDIR );

This would give you an array of all directories matching $input (if you
want all files, leave out the GLOB_ONLYDIR). This way you could specify
files like this:

'/home/whatever/{foo,bar}/*'

But then, this might not help you at all with your current project. I
hope that my remarks are somehow helpful.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux ā avoir tort qu'ils ont raison!
(Coluche)
johannes.heinen@googlemail.com
Guest
 
Posts: n/a
#5: Nov 2 '08

re: SplFileInfo issues


But then, this might not help you at all with your current project. I
Quote:
hope that my remarks are somehow helpful.
Thanks a lot for your efford, there is probably more than one way to
solve fs-path handling, but i asked for experiences and best
practices, so i m looking forward to make it your way. Yesterday i
tried realpath - i works fine on my ubuntu-machine but has not yet
been tested on windows. So i think that i really will drop realpath()
again and use the solution with (r/l)trim to have full control of my
"path appearences".

Perhaps one annotation on my experience with SplFileInfo(): I tried to
create a SplFileInfo-Child object and therefore implemented a
MySplFileInfo::exists()-Method. Calling this method before
SplFileInfo::isDir() or so gives total control of the Exception thrown
by SplFileInfo - even if the linked file does not exist physically.
This allows you to write an API that accepts SPLFileInfo-Objects
rather than String-Pathnames, so you have a better, encapsulated way
to deal with paths (i doesn't matter if the end-user writes
MySplFileInfo::__construct("/path/folder") or ("/path/folder/") - the
logic dealing with slashes suggested by you is directly implemented in
the instance-constructor itself. And you mostly avoid using "native"
fs-functions like isDir() etc... but this is merely a question of
design or taste.

SplFileInfo even allows the creation of physically non-existent paths,
but calling isDir() or open will throw a native Exception as far as i
remember, so a ::exists() method with a simple (file_exists($this-
Quote:
>getPathname())) or using __toString() may be useful.
Have a nice day,
Johannes
johannes.heinen@googlemail.com
Guest
 
Posts: n/a
#6: Nov 2 '08

re: SplFileInfo issues


But then, this might not help you at all with your current project. I
Quote:
hope that my remarks are somehow helpful.
Thanks a lot for your efford, there is probably more than one way to
solve fs-path handling, but i asked for experiences and best
practices, so i m looking forward to make it your way. Yesterday i
tried realpath - i works fine on my ubuntu-machine but has not yet
been tested on windows. So i think that i really will drop realpath()
again and use the solution with (r/l)trim to have full control of my
"path appearences".

Perhaps one annotation on my experience with SplFileInfo(): I tried to
create a SplFileInfo-Child object and therefore implemented a
MySplFileInfo::exists()-Method. Calling this method before
SplFileInfo::isDir() or so gives total control of the Exception thrown
by SplFileInfo - even if the linked file does not exist physically.
This allows you to write an API that accepts SPLFileInfo-Objects
rather than String-Pathnames, so you have a better, encapsulated way
to deal with paths (i doesn't matter if the end-user writes
MySplFileInfo::__construct("/path/folder") or ("/path/folder/") - the
logic dealing with slashes suggested by you is directly implemented in
the instance-constructor itself. And you mostly avoid using "native"
fs-functions like isDir() etc... but this is merely a question of
design or taste.

SplFileInfo even allows the creation of physically non-existent paths,
but calling isDir() or open will throw a native Exception as far as i
remember, so a ::exists() method with a simple (file_exists($this-
Quote:
>getPathname())) or using __toString() may be useful.
Have a nice day,
Johannes
Closed Thread