2017-06-08 13 views
8

file_existsが機能しません。私はいくつかの例を見てきましたが、まだ行っていません。プログラムはファイルを検出しません。私のファイルのパスは/var/www/osbs/PHPAPI/recording.mp3で、ウェブサイトのルートはosbsの中にあります。このファイルの場所はPHPAPIの内部にあるため、私はfile_put_contentsにフルパスを入れません。プログラムは元のrecording.mp3を作成できますが、追加されたバージョンは作成できません。ループ中にphp5内でfile_exists()が機能しないwhileループ

<?php 
$actual_name = pathinfo("PHPAPI/recording.mp3",PATHINFO_FILENAME); 
$original_name = $actual_name; 
$extension = pathinfo("PHPAPI/recording.mp3",PATHINFO_EXTENSION); 

if ($_GET["RecordingUrl"]) { 
    if (file_exists("/var/www/osbs/PHPAPI/".$actual_name.".".$extension)) { 
     $actual_name = find_new_name($original_name, $extension); 
    } 
    else { 
     $actual_name = $original_name; 
    } 
    $name = $actual_name.".".$extension; 
    file_put_contents($name, file_get_contents($_GET["RecordingUrl"])); 
} 

function find_new_name ($file, $extension) { 
    $name = $file.".".$extension; 
    $i = 0; 
    while(file_exists("/var/www/osbs/PHPAPI/".$name)){ 
     $new_name = $file.$i; 
     $name = $new_name.".".$extension; 
     $i++; 
    } 
    return $new_name; 
} 
?> 
+0

これは巨大なセキュリティ上の問題です: 'file_get_contents($ _GET [" RecordingUrl "])' – greg0ire

+0

@ greg0ireそれはテストのためだとわかります。私は通常、$ _POSTを使用します – fixnode

+2

あなたは面白いです – greg0ire

答えて

2

問題はfile_put_contentsです。フルパスを指定する必要があり、ファイル名のみを指定します。それを使用する直前にechoを入力して$nameを試してみると、パスではなくファイル名であることがわかります。

相対パスに依存することなく、場合によっては絶対パスに頼るのではなく、ファイルの先頭に定数を設定することをお勧めします。

  1. const SAVE_PATH = "/var/www/osbs/";
  2. はどこでも新しい定数を使用して定義された:私は何が変わった

    <?php 
    const SAVE_PATH = "/var/www/osbs/"; 
    
    $actual_name = pathinfo(SAVE_PATH."PHPAPI/recording.mp3",PATHINFO_FILENAME); 
    $original_name = $actual_name; 
    $extension = pathinfo(SAVE_PATH."PHPAPI/recording.mp3",PATHINFO_EXTENSION); 
    
    if (isset($_GET["RecordingUrl"]) && $_GET["RecordingUrl"]) { 
        if (file_exists(SAVE_PATH."PHPAPI/".$actual_name.".".$extension)) { 
         $actual_name = find_new_name($original_name, $extension); 
        } 
        else { 
         $actual_name = $original_name; 
        } 
        $name = $actual_name.".".$extension; 
    
        file_put_contents(SAVE_PATH.'PHPAPI/'.$name, file_get_contents($_GET["RecordingUrl"])); 
    } 
    
    function find_new_name ($file, $extension) { 
        $name = $file.".".$extension; 
        $i = 0; 
        while(file_exists(SAVE_PATH."PHPAPI/".$name)){ 
         $new_name = $file.$i; 
         $name = $new_name.".".$extension; 
         $i++; 
        } 
        return $new_name; 
    } 
    ?> 
    

    。時には相対的なものもなく絶対的なものもありません。それは絶対的なものです。

  3. file_put_contentsで定数を使用します(THISは、実際の修正です、あなたがここに FULLパスが必要)が
  4. は、それが設定されていないとき、そうしないと、PHPの警告を取得し、必ずRecordingUrl ISSETを作るために追加のチェックを追加しました。
2

パスについてはどうなりますか? /PHPAPI/PHPAPIの中のファイルを探しますが、予期したのは/var/www/osbs/PHPAPI/ではありません。代わりにPHPAPI/$filenameを確認する必要があります。

+0

/var/www/osbs/PHPAPIはサーバーにSSH接続する場合はフルパスですが、このドメインのApacheドキュメントルートはosbsフォルダです。/PHPAPIはフォルダで、recording.mp3は元のファイルです。 /PHPAPI/recording.mp3はパスです。元のファイルが存在しない場合は$ _GETから作成しますが、それが存在する場合はカウンタ番号を追加します – fixnode

+0

これは質問への回答を提供しません。批評をしたり、著者の説明を求めるには、投稿の下にコメントを残してください。 - [レビューの投稿](レビュー/低品質の投稿/ 16357314) –

+0

@ShawnMehan私は非常にはっきりと答えたTalusesに答えるよ。 – fixnode

2

問題は、スクリプトの最初の行にあるように思わ:

$actual_name = pathinfo("PHPAPI/recording.mp3", PATHINFO_FILENAME); 

これは$actual_filenamerecording.mp3を割り当てます。拡張子をファイル名に連結してrecording.mp3.mp3をチェックします。私はPATHINFO_BASENAMEを使用して、ファイル名の拡張子を返すと思います。

+0

これは役に立ちません。パスを(file_exists( "/ PHPAPI/recording.mp3"))に変更しても、file_existsはまだ失敗します – fixnode

+1

あなたの[include path](http://php.net/manual/en/function.set-include -パス。php)には、PHPAPIというフォルダを含むディレクトリが含まれていません。 get_include_pathをダンプしてフォルダを探すディレクトリのリストを取得します。ルートディレクトリがそこにない場合は、最初に追加するか、フォルダのフルパスを使用する必要があります。 – sjdaws

1

あなたは、ファイルのURLとそのPATHの間で混乱している

あなたhttdoc(public_htmlのか)ルートであるの/ var/www /のosbs/PHPAPI

しかし、あなたのファイルシステムルートは '/'

Try

file_put_contents(__DIR__.'/'.$name, file_get_contents($_GET["RecordingUrl"])); 

悪い慣行の多くは、あなたが)ますfile_put_contents(とパスを忘れてしまった

1

あなたのコードです。 それは次のようになります。

file_put_contents("PHPAPI/".$name, file_get_contents($_GET["RecordingUrl"])); 

または:

file_put_contents("/var/www/osbs/PHPAPI/".$name, file_get_contents($_GET["RecordingUrl"])); 
2

あなたはfind_new_name()機能であなたのすべての論理を配置する必要があります。それはあなたのコードをより明確にしました

if ($_GET["RecordingUrl"]) { 
    $name = find_new_name("PHPAPI/recording.mp3"); 
    file_put_contents($name, file_get_contents($_GET["RecordingUrl"])); 
} 

function find_new_name($name) { 
    $info = pathinfo($name); 
    $name = $info['basename']; 
    $i = 0; 
    while (file_exists("$info[dirname]/$name")) { 
    $name = sprintf('%s%d.%s', $info['filename'], ++$i, $info['extension']); 
    } 
    return "$info[dirname]/$name"; 
} 
+0

これを指摘するだけの答えが、私はこれが主要な原因だと思います。 Sane関数FTW。しかし、私はこれをさらに改良して、ファイル名の既存の番号を再利用できるようにすることができます。フリーで検出された後にファイルが作成された場合(たとえば、パラレルアップロード)、* next * 。 – hakre

0

'file_exists'とfstatのようないくつかのファイル呼び出しはphpによってキャッシュされます。これは、file_existsのマニュアルに記載されています。ファイルが存在しないときの最初の呼び出しは保存され、後続の呼び出しで返されます。呼び出しの間に 'clearstatcache()'を使用してキャッシュをクリアします。

0

「少し」リファクタリング:

  1. 絶対パスどこでも
  2. トランスペアレント機能、より自明名、悪意のある入力($ _POST実際にカットしていませんに対する引数
  3. 保護の簡素使用それ)
  4. なぜますfile_put_contents()あなたが実際に(コピーする)

    <?php 
    
    define("SRC_PATH", "/var/www/osbs/whereverYourSrcIs/"); 
    define("SAVE_PATH", "/var/www/osbs/PHPAPI/"); 
    
    function findAvailableName($name) { 
        $i = 1; 
        $pathinfo = pathinfo($name); 
        while(file_exists($name)) { 
         $name = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . "." . $i++ . "." . $pathinfo['extension']; 
        } 
        return $name; 
    } 
    
    if (isset($_GET["RecordingUrl"]) && $_GET["RecordingUrl"]) { 
    
        if (strpos('/' . $_GET['RecordingUrl'] . '/', '/../') !== false) { 
         die("invalid input, don't be evil"); 
        } 
    
        copy(SRC_PATH . $_GET["RecordingUrl"], findAvailableName(SAVE_PATH . "recording.mp3")); 
    } 
    
関連する問題