SplFileInfo issues

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • johannes.heinen@googlemail.com

    SplFileInfo issues

    Hello,

    i recently fell into trouble while extending a few Spl-Classes
    (SplFileInfo, RecursiveDirect oryIterator ...) for implementing a so
    called "filemanage r".

    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::ge tBasename() 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äs e.jpg
    getBaseName(/home/hans/wurst/) =wurst
    getBaseName(/home/hans/wurst)=wurst

    But it doesn't, obviously SplFileInfo::ge tBaseName() implements the
    same logic as SplFileInfo::ge tFileName()

    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::ge tPathName()

    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

    #2
    Re: SplFileInfo issues

    johannes.heinen @googlemail.com schrieb:

    [I have]
    new SplFileInfo(/home/www/cms/public/filebase/)->getFilename( ) returns
    empty value
    new SplFileInfo(/home/www/cms/public/filebase)->getFilename( ) returns
    "filebase"
    [I want]
    getBaseName(/home/hans/wurst/käse.jpg")=>käs e.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)

    Comment

    • johannes.heinen@googlemail.com

      #3
      Re: SplFileInfo issues

      On Nov 1, 2:20 pm, Thomas Mlynarczyk <tho...@mlynarc zyk-webdesign.de>
      wrote:
      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

      Comment

      • Thomas Mlynarczyk

        #4
        Re: SplFileInfo issues

        johannes.heinen @googlemail.com schrieb:
        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_SEPAR ATOR )

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

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

        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)

        Comment

        • johannes.heinen@googlemail.com

          #5
          Re: SplFileInfo issues

          But then, this might not help you at all with your current project. I
          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::is Dir() 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($t his-
          >getPathname()) ) or using __toString() may be useful.
          Have a nice day,
          Johannes

          Comment

          • johannes.heinen@googlemail.com

            #6
            Re: SplFileInfo issues

            But then, this might not help you at all with your current project. I
            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::is Dir() 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($t his-
            >getPathname()) ) or using __toString() may be useful.
            Have a nice day,
            Johannes

            Comment

            Working...