権限の確認用関数を用意
Linuxサーバでは権限の問題でアップロード処理が失敗することはよくあるので
アップロードの失敗原因を出来るだけ分かりやすくする関数を用意
app/Services/StoragePermissionService.php
<?php
namespace App\Services;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
class StoragePermissionService
{
public function check(string $directory = 'spec-md'): array
{
$disk = Storage::disk('public');
$path = $directory.'/_perm_check.txt';
$writable = false;
$deletable = false;
$errorMsg = null;
try {
$writable = $disk->put($path, 'ok');
} catch (\Throwable $e) {
$writable = false;
$errorMsg = 'Write error: '.$e->getMessage();
Log::error('Storage write failed', [
'path' => $disk->path($path),
'error' => $e->getMessage(),
]);
}
if ($writable) {
try {
$deletable = $disk->delete($path);
} catch (\Throwable $e) {
$deletable = false;
$errorMsg = 'Delete error: '.$e->getMessage();
Log::error('Storage delete failed', [
'path' => $disk->path($path),
'error' => $e->getMessage(),
]);
}
}
$result = [
'disk' => 'public',
'dir' => $directory,
'writable' => (bool) $writable,
'deletable' => (bool) $deletable,
'path' => $disk->path($path),
'error' => $errorMsg,
];
Log::info('Storage permission check result', $result);
return $result;
}
}
コントローラーでの使用例
mdファイルをstorage/app/public/spec-md
フォルダ内に保存するstore関数内に設置しました。
app/Http/Controllers/SpecMdController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use App\Services\StoragePermissionService;
class SpecMdController extends Controller
{
public function index()
{
$dir = storage_path('app/public/spec-md');
$files = is_dir($dir) ? array_values(array_filter(scandir($dir), fn($f) =>
!in_array($f, ['.','..']) && is_file("{$dir}/{$f}")
)) : [];
$docs = array_map(fn($f) => asset("storage/spec-md/{$f}"), $files);
return view('spec-md.index', compact('docs'));
}
public function store(Request $request, StoragePermissionService $permService)
{
// ファイルアップロード前に権限チェック
$check = $permService->check('spec-md');
if (!$check['writable']) {
return back()->with('status', '保存先ディスクに書き込みできません。管理者に連絡してください。');
}
Log::info('upload debug', [
'hasFile' => $request->hasFile('mdfile'),
'isValid' => $request->file('mdfile')?->isValid(),
'origName' => $request->file('mdfile')?->getClientOriginalName(),
'clientMime' => $request->file('mdfile')?->getClientMimeType(),
]);
$validated = $request->validate([
'mdfile' => ['required','file','mimetypes:text/markdown,text/plain','max:10240'],
]);
$file = $validated['mdfile'];
if (!$file) {
return back()->with('status', 'ファイルが取得できませんでした。');
}
Storage::disk('public')->makeDirectory('spec-md');
$ext = $file->getClientOriginalExtension();
$name = now()->format('Ymd_His') . '_' . Str::random(8) . '.' . $ext;
$savedPath = Storage::disk('public')->putFileAs('spec-md', $file, $name);
$abs = Storage::disk('public')->path($savedPath);
$url = asset('storage/spec-md/'.$name);
Log::info('spec-md saved', compact('savedPath','abs','url'));
return back()->with('status', "アップロードOK: {$savedPath}");
}
}
ポイント
まず判定用のサービスクラスを下記で呼び出します。
use App\Services\StoragePermissionService;
次に、store関数内 の以下のコードで判定してログに書き込んでいます。
// ファイルアップロード前に権限チェック
$check = $permService->check('spec-md');
if (!$check['writable']) {
return back()->with('status', '保存先ディスクに書き込みできません。管理者に連絡してください。');
}
ログ出力例
書き込みできなかった場合
laravel.log
[2025-09-06 14:22:10] local.ERROR: Storage write failed {"path":"/var/www/.../storage/app/public/spec-md/_perm_check.txt","error":"Permission denied"}
[2025-09-06 14:22:10] local.INFO: Storage permission check result {"disk":"public","dir":"spec-md","writable":false,"deletable":false,"path":"/var/www/.../storage/app/public/spec-md/_perm_check.txt","error":"Write error: Permission denied"}
書き込みはできたけど削除できなかった場合
laravel.log
[2025-09-06 14:22:20] local.ERROR: Storage delete failed {"path":"/var/www/.../storage/app/public/spec-md/_perm_check.txt","error":"Permission denied"}
[2025-09-06 14:22:20] local.INFO: Storage permission check result {"disk":"public","dir":"spec-md","writable":true,"deletable":false,"path":"/var/www/.../storage/app/public/spec-md/_perm_check.txt","error":"Delete error: Permission denied"}