John Davidson

PHP and long UNC paths (Windows)

0 comments
Message:


Starting with PHP 7.1, long Windows path are usable, as mentioned here (second to last paragraph of first section): "Long paths support is transparent. Paths longer than 260 bytes get automatically prefixed with \\?\. The max path length is limited to 2048 bytes."


This works fine for local files (i.e. "C:" drive), but not for UNC paths.


There is an equivalent to \\?\ for those, \\?\UNC\, but it doesn't seem to work/be implemented.


Am I missing something? Is it a 'bug'? Is it planned for the future?


<?php

$longPathLocal = 'C:\Path\Longer\Than\260\Characters\File.ext';
$longPathUNC = '\\\Server\Path\Longer\Than\260\Characters\File.ext';

echo filesize($longPathLocal); // Shows size of file
echo filesize($longPathUNC); // Shows nothing (returns false)

//Tried $longPathUNC = '\\\?\UNC\Server...', but same result

Windows Explorer doesn't allow you to create a filename longer than 260 characters. You have to create a couple of very long sub-folders, then move a file there with a name that will make the complete path exceed 260 characters.


Here's a code sample that demonstrate the issue, writing files on both local and UNC:


$roots = ['Local' => 'C:\TestDocs\\',
'UNC' => '\\\server\TestLongUNC\\'];
foreach($roots as $loc => $path) {
//Create long sub-folder structure
echo $loc.' root: '.$path.PHP_EOL;
$len = strlen($path);
$fold_len = 150 - $len;
$newFold = generateRandomString($fold_len);
$path .= $newFold;
// $path is now 150 char. long
mkdir($path);
$newFold = generateRandomString(90);
$path .= '\\'.$newFold;
// $path is now 240 char. long
mkdir($path);

//Create both short and long filenames
$path .= '\\';
$files = ['Short' => 'Short.txt', // Total len.: 251
'Long' => 'LongerFilenameAbove260Chars.txt']; // Total len.: 273
foreach ($files as $size => $fname) {
$fpath = $path.$fname;
if (@file_put_contents($fpath, 'I\'m the '.$size.' file.')) {
echo $size.' file written';
} else {
echo 'Unable to write '.$size.' file';
}
echo ' to '.$fname.' (total path length: '. strlen($fpath).' chars)'.PHP_EOL;
}
echo PHP_EOL.'========================='.PHP_EOL.PHP_EOL;
}

function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}


My Answer:
It seems that the support for long UNC paths in PHP is not as straightforward as for local paths. The \\?\UNC\ prefix does not seem to work as expected.

One workaround for this issue is to use the subst command in Windows to create a virtual drive letter for the long UNC path. This way, you can access the long UNC path as if it were a local path with a drive letter.

Here's an example of how you can use the subst command:

php
$longPathUNC = '\\\Server\Path\Longer\Than\260\Characters\File.ext';

// Create a virtual drive letter for the UNC path
exec('subst Z: "'.$longPathUNC.'"');

// Access the file using the virtual drive letter
echo filesize('Z:\File.ext');

// Remove the virtual drive letter when done
exec('subst Z: /d');


This way, you can work with long UNC paths in PHP by temporarily assigning them a virtual drive letter.

Rate this post

5 of 5 based on 4423 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us