Файл не найден по пути при попытке копирования

Я пытаюсь скопировать файл из одного места в другое. Я почти уверен, что местоположение правильное, но я все еще получаю ошибку в заголовке.

Вот код:

$oDirectory = new \RecursiveDirectoryIterator($extractFolder.'/res');
$oIterator = new \RecursiveIteratorIterator($oDirectory);
foreach($oIterator as $oFile) {
    if ($oFile->getFilename() == 'icon.png') {
        $icons[filesize($oFile->getPath().'/icon.png')] = $oFile->getPath().'/icon.png';
    }
}
asort($icons);
print_r($icons);
$icon_source = end($icons);
echo $icon_source;
$generated_icon_file = str_slug($packagename.$version).'.png';
Storage::copy($icon_source, $generated_icon_file);

print_r возвращает (что означает, что файлы существуют):

Array ( [19950] => /var/www/apk.land/storage/extracted_apks/res/drawable-xxhdpi-v4/icon.png [31791] => /var/www/apk.land/storage/extracted_apks/res/drawable-xxxhdpi-v4/icon.png [6979] => /var/www/apk.land/storage/extracted_apks/res/drawable-hdpi-v4/icon.png [10954] => /var/www/apk.land/storage/extracted_apks/res/drawable-xhdpi-v4/icon.png )

Эхо возвращается:

/var/www/apk.land/storage/extracted_apks/res/drawable-xxxhdpi-v4/icon.png

И точная ошибка:

Файл не найден по пути: var/www/apk.land/storage/extracted_apks/res/drawable-xxxhdpi-v4/icon.png

P.S. Функция PHP copy работает просто великолепно.

Я не могу найти проблему здесь.

Какие-либо предложения?


person Alex    schedule 19.08.2015    source источник
comment
Похоже, что var истекает кровью как часть начала веб-адреса. Это предназначено?   -  person JJFord3    schedule 19.08.2015
comment
@JJFord3 Что ты имеешь в виду? Я не понял :)   -  person Alex    schedule 19.08.2015
comment
Путь в ошибке: var/www/apk.land/storage/extracted_apks/res/drawable-xxxhdpi-v4/icon.png Должно ли это быть www/apk.land/storage/extracted_apks/res/drawable-xxxhdpi-v4 /icon.png?   -  person JJFord3    schedule 19.08.2015
comment
Это локальный путь, а не веб-адрес, и он начинается с /var/.   -  person Alex    schedule 19.08.2015
comment
Похоже, что драйвер хранилища удаляет начальную косую черту перед путем при копировании, обратите внимание, что в сообщении об ошибке написано var/www/..., а не /var/www/... Не знаю, почему.   -  person Joel Hinz    schedule 19.08.2015
comment
Я тоже это заметил и даже поставил перед ним еще один '/', но он все равно показывает его без него.   -  person Alex    schedule 20.08.2015
comment
Он показывает только путь к файлу... нечего проверять, действительно он существует или нет... но можете ли вы открыть это изображение из браузера или из чего-то еще?   -  person Safoor Safdar    schedule 17.09.2015
comment
Да, я могу, и, как я уже говорил в своем вопросе, я могу скопировать его с помощью функции PHP copy.   -  person Alex    schedule 17.09.2015
comment
так что просто замена Storage::copy($icon_source, $generated_icon_file); на copy($icon_source, $generated_icon_file); работает?   -  person Halayem Anis    schedule 17.09.2015


Ответы (5)


Прежде всего, если вы используете Laravel Storage Facade и базовую Flysystem, вы должны знать , что он не предназначен для работы с абсолютными путями, как вы. Преимущество этого заключается в том, что вы потенциально можете работать с разными дисками хранения, каждый из которых имеет собственную конфигурацию, которую можно установить в вашем файле config/filesystems.php.

Предполагая, что вы ничего там не меняли, «диск» по умолчанию будет локальным с корнем storage_path('app') (= путь к вашей папке/приложению хранения laravel)

Если вы хотите знать, почему это не работает, мы должны взглянуть на исходный код, который вы найдете в следующем коде в файле vendor\league\flysystem\src\Filesystem.php

public function copy($path, $newpath)
{
    $path = Util::normalizePath($path); // <-- this will strip leading /
    $newpath = Util::normalizePath($newpath);
    $this->assertPresent($path); // this will cause the error in your case, because assertion cannot be fullfilled in case of missing leading / 
    $this->assertAbsent($newpath);

    return $this->getAdapter()->copy($path, $newpath); // calls the copy of your Adapter, assuming local in your case
}

Итак, посмотрите, что произойдет, если будет вызвана $this->getAdapter()->copy($path, $newpath):

Файл (предполагается локальный диск хранения): vendor\league\flysystem\src\Adapter\Local.php

public function copy($path, $newpath)
{

    $location = $this->applyPathPrefix($path);
    $destination = $this->applyPathPrefix($newpath);
    $this->ensureDirectory(dirname($destination));
    return copy($location, $destination);
}

Линия

$location = $this->applyPathPrefix($path);

добавит корневой путь, как указано в config/filesystems.php

'диски' => [

    'local' => [
        'driver' => 'local',
        'root'   => storage_path('app'),
    ],

Как я вижу в вашем коде, ваши файлы не хранятся в хранилище/приложении, поэтому я думаю, вам нужно изменить это на «root» => storage_path()

Поэтому, если вы хотите использовать Storage::copy(), вам нужно просто указать пути относительно этой папки. И так как трудно понять, как вы могли бы добиться этого, взгляните на это.

    foreach($oIterator as $oFile) {
        if ($oFile->getFilename() == 'icon.png') {
            $icons[filesize($oFile->getPath().'/icon.png')] = $oIterator->getSubPath().'/icon.png';
        }
    }

Существует RecursiveDirectoryIterator::getSubPath (хотя и совершенно недокументированный, который вернет вам текущий подпуть ваших итераций.В вашем случае относительно $extractFolder.'/res'.

Теперь вы должны убедиться, что вы звоните

Storage::copy($icon_source, $generated_icon_file);

Где $icon_source и $generated_icon_file относятся к вашему определенному «корню».

person shock_gone_wild    schedule 20.09.2015

Вы сказали, что ошибка такая:

File not found at path: var/www/apk.land/storage/extracted_apks/res/drawable-xxxhdpi-v4/icon.png

Здесь ошибка говорит о том, что он не может найти в var/www, что означает, что он ищет apk.land/var/www, тогда как ваш файл находится где-то в /var/www. Быстро исправить это можно с помощью протокола file. Просто используйте его как:

file:///var/www/storage/apk.land/storage/extracted_apks/res/drawable-xxxhdpi-v4/icon.png
person Aditya Giri    schedule 17.09.2015

Попробуйте использовать File::copy($file, $dest) вместо of Storage::copy($old, $new)
File::copy() — это оболочка для функции PHP copy()

person Halayem Anis    schedule 17.09.2015

Вставьте / перед var/www/apk.land/storage/extracted_apks/res/drawable-xxxhdpi-v4/icon.png

Путь указан относительно текущего каталога. Купить, если вы добавите /, путь будет абсолютным из корневого каталога.

person Alejandro Salamanca Mazuelo    schedule 19.09.2015
comment
Не могли бы вы добавить дополнительное объяснение того, почему это решит проблему? - person AJF; 19.09.2015
comment
Добавление / не решит проблему, так как ведущие / удаляются во время Storage::copy() - person shock_gone_wild; 20.09.2015
comment
У него уже есть /, как вы можете видеть в моем коде, но он удален Laravel. - person Alex; 24.09.2015

вы должны выбрать правильный диск примерно так

$file2 ='public/'.$page->thumbnail;

$destination = 'public/bundles/ttt.png';

if( Storage::disk('local')->exists($file2)){

      Storage::disk('local')->copy($file2,$destination);
 }
person aitbella    schedule 26.04.2019