tags:

views:

148

answers:

2

Is there a PHP equivalent function to the Python os.path.normpath()?
Or how can i get the exactly same functionality in PHP?

+2  A: 

Yes, the realpath command will return a normalized path. It's similar to a combined version of Python's os.path.normpath and os.path.realpath.

However, it will also resolve symbolic links. I'm not sure what you'd do if you didn't want that behavior.

R. Bemrose
PHP's realpath would be more like the equivalent of os.path.abspath() or os.path.realpath()
VolkerK
@Gordon: PHP's realpath is more like a combined version of Python's os.path.normpath and os.path.realpath.
R. Bemrose
I think this is the closest you can get to `os.path.normpath()` functionality. Either this or there is no (at least) built-in function for this. It depends on what the OP really needs...
Felix Kling
No, it is not the same. PHP checks what ever this path exist on local computer. Python only calculates path - that is what I need.Simple test in php and python. PHP: echo realpath('/bin/../lib/'); echo realpath('/bin2/../lib2/'); - will return '/lib' and empty string;Python: print os.path.normpath('/bin/../lib') -> /lib, print os.path.normpath('/bin2/../lib2') -> /lib2
troex
@troex: Actually, PHP should return FALSE for the non-existent one. I don't see any other PHP built-ins that just canonicalize paths, though.
R. Bemrose
+1  A: 

Here is my 1:1 rewrite of normpath() method from Python's posixpath.py in PHP:

function normpath($path)
{
    if (empty($path))
        return '.';

    if (strpos($path, '/') === 0)
        $initial_slashes = true;
    else
        $initial_slashes = false;
    if (
        ($initial_slashes) &&
        (strpos($path, '//') === 0) &&
        (strpos($path, '///') === false)
    )
        $initial_slashes = 2;
    $initial_slashes = (int) $initial_slashes;

    $comps = explode('/', $path);
    $new_comps = array();
    foreach ($comps as $comp)
    {
        if (in_array($comp, array('', '.')))
            continue;
        if (
            ($comp != '..') ||
            (!$initial_slashes && !$new_comps) ||
            ($new_comps && (end($new_comps) == '..'))
        )
            array_push($new_comps, $comp);
        elseif ($new_comps)
            array_pop($new_comps);
    }
    $comps = $new_comps;
    $path = implode('/', $comps);
    if ($initial_slashes)
        $path = str_repeat('/', $initial_slashes) . $path;
    if ($path)
        return $path;
    else
        return '.';
}

This will work exactly the same as os.path.normpath() in Python

troex