PHPでのファイル書き込みとパーミッションエラー解決法

  • このエントリーをはてなブックマークに追加
  • Pocket

スポンサードリンク

PHPでテキストファイルなどのファイルへの、文字列やデータの書き込み方法をご紹介します。

ファイル操作は敷居が高いイメージもあり、なかなか手を出さない人も多いのではないでしょうか。

しかし、実際にプログラムしてみると簡単に書き込みや読み込みが出来ることが分かります。

今回はいくつかの方法で簡単にファイルに書き込めるプログラムをご紹介します。

それと、何故かエラーで書き込めないという人もいるでしょう。

パーミッションと呼ばれる権限を適切に設定すれば、PHPプログラムで簡単にファイルへの書き込みができます。

そういったエラーの対処法も併せてご紹介します。

 

file_put_contents関数で簡単に書き込み

オープンからクローズまでを1つの関数で簡略化

file_put_contents()を使えばfopen()fwrite()fclose()による一連のファイルオープンから書き込み、クローズまでを1つの関数で簡単に処理できます。

*「ここはイムルのむらです。

上記のように、簡単にファイルに書き込めました。

file_put_contentsの構文

file_put_contents ( 書き込みたいファイル名またはパス , 書き込むデータ-文字列や配列など (, フラグ(省略可)));

書き込むデータは文字列だけでなく、配列もOKです。

もし、指定したファイルが存在しなかったら、そのファイル名で新規にファイルを作成してくれます。

 

第三引数のフラグは以下の3種類で、省略も可能です。

  1. FILE_USE_INCLUDE_PATH
    ファイルを、インクルードディレクトリも含めて探す
  2. FILE_APPEND
    ファイルがすでに存在する場合、追記モードで上書きせずに書き込む
  3. LOCK_EX
    書き込み処理中にファイルにロックを掛け、他者による上書き等を防ぐ

よく使うのは2と3かと思います。

ファイルを、すでにあるデータの続きから追記したい場合はフラグ2を、排他的ロックをかけ他者に邪魔されたくない場合はフラグ3を指定しましょう。

何も指定しなければファイルをまっさらにしての新規書き込みとなり、次項で説明しているfopen()wモードのような動作になります。

※PHP5.2.5以前ではLOCK_EXにバグがあり、上手く動作しないようです。

fwrite関数で書き込み

文字列をファイルに書き込みます。

fwrite()は、通常fopen()fclose()と併用して書き込み処理をします。

fwriteの使い方

*「ここはイムルのむらです。

上記のような簡単なプログラムで、ファイルに書き込めました。

file_put_contentsよりは

fwriteでの書き込みの流れ

fwrite()で書き込む際は、通常は上記サンプルのようにfopen()fclose()をセットで使います。

fwrite()で書き込む際の流れは以下のとおりです。

 

  1. fopen()で書き込むファイルを所定のモードで開く
    (書き込みモード、読み込みモードなど)
  2. fwrite()でファイルに書き込む
  3. fclose()でファイルを閉じる

ここで使う3つのファイルの関数は次で詳細を説明します。

ファイル関数の構文

fopen関数

ファイルをオープンする。

fopen ( 開くファイル名またはパス , 開くモード ( , include_path (省略可)));

fwrite()を使うためには、まず書き込むファイルをオープンさせなくてはいけません。

もし、指定したファイルが存在しなかったら、そのファイル名で新規にファイルを作成してくれます。

そしてオープンする際にモードを指定します。

書き出しモードはw読み込みはrなど、行いたい処理によってモードを指定します。

モードは以下の一覧表でご確認ください。

fopenのモード一覧

モードポインタ
の位置
読み込み/書き出し備考
r先頭読み込みのみ
r+先頭読み込み/書き出し
w先頭書き出しのみファイルがなければ作成
ファイルの中身を全削除し新規書き込み
w+先頭読み込み/書き出し
a終端書き出しのみファイルがなければ作成
データは追記で上書きせずに書き込む
a+終端読み込み/書き出し
x先頭書き込みのみファイルが存在する場合はエラー、なければ作成
x+先頭読み込み/書き出し
c先頭書き込みのみファイルがなければ作成
ファイルは排他的ロックで他者と処理が重複しない
c+先頭読み込み/書き出し

ファイルの中身をまっさらにした後、新規で書き込むwモード、すでにあるデータの続きから追記するaモードを使うことが多いようです。

fwrite関数

ファイルに書き込む。

fwrite ( ファイルポインタ , 書き込む文字列 (, 文字列の長さ(省略可)));

ファイルポインタは、書き込むファイルをfopen()で開いたものが入ります。

最初はよく分かりませんが、上記のようにやるもんなんだと特に考えずにコピーして動かしてみましょう。

fclose関数

ファイルを閉じる。

fclose ( fopenで開いた閉じたいファイルポインタ );

ファイルを開くとリソースを使うため、処理が終わったら速やかにファイルを閉じて、リソースを解放してやりましょう。

 

最初のサンプルにあったreadfile()は、ファイルの中身を出力してくれます。

この関数は記述しなくても書き込みは問題なくできますよ。

 ファイルに書き込みができない

ファイルに書き込む際に、以下のようなエラーが出た場合パーミッションエラーといい、「あなたはファイルに書き込む権限はありませんよ。」というエラーです。

Warning: file_put_contents(memo.txt): failed to open stream: Permission denied in…

ファイルに書き込めるようにパーミッションを設定

ファイルに書き込むためには、ユーザーに書き込み権限を与えてやる必要があります。

そのためにはパーミッション(アクセス権)を書き込めるグレードに変更してあげましょう。

パーミッションとは?

パーミッションとは、ファイルやディレクトリに対するアクセス権のことを言います。

一般的にwebでは複数のユーザーが1台のマシンを共有するため、自分のファイルを他人に不正に操作されないためにアクセス権(パーミッション)を設定することが出来ます。

出典:ロリポップ!レンタルサーバー

chmod関数でパーミッションを変更

PHPでパーミッションを変更するにはchmod()を使います。

ファイル名を変数に格納する際chmod()でパーミッションも一緒に設定するとよいでしょう。

chmodの構文

chmod( パーミッションを変更するファイル名 , 変更後のパーミッション );

書き込み権限はセキュリティ上606を指定するのが望ましいですが、レンタルサーバーによっては動かないケースもあるようで、その際は666を設定します。

ちなみに、第二引数のパーミッションは0を付けて4桁で設定しないとエラーになります。

06660606のように設定しましょう。

 

環境によってはパーミッションは自動で設定される場合もありますが、パーミッションエラーの際は権限を変更しましょう。

PHPで変更せずに、FTPでファイルを直接いじって、パーミッションを変更することもできます。

スポンサードリンク

  • このエントリーをはてなブックマークに追加
  • Pocket

コメント

  1. 八雲 より:

    いつも大変お世話になっております。
    解かり易いサイトなのでしばらく滞在しております。

    パーミッションの数字の意味合いがいまいち理解できません。
    8進数で書くのは解かるのですが、それぞれの数字の意味が理解できません。
    他のサイトで見ると、

    読み出し可 = 4
    書き込み可 = 2
    実行可 = 1
    読み書き可 ならば 4+2 で 6、読み出しと実行可ならば 4+1 で5のようになります。

    と書いてあるのですが、読み書き可だと6を8進数にして書けばいいのか...それだと、0006 でいいのか...?理解できない...という状態です。
    大変、御無礼なのですが、ご指導いただければと思い書き込んでしまいました。

    1. flatFlag より:

      コメントありがとうございます。
      パーミッションの件ですが、当方でも知識がないため解説ができませんm(_ _)m
      不勉強で申し訳ないです。
      他にもいろいろ解説しておりますので、ぜひごゆっくり滞在していってください。

  2. 八雲 より:

    いつもありがとうございます。
    解かり易くいいサイトです。
    しばらく滞在させていただきます。

  3. 通りすがり より:

    多分、考え方はあってると思うよ
    0006の場合、オーナーとグループは何も出来ない?
    0606の場合、オーナーとその他では読み書き可能
    2番目の数値はオーナーに対して
    3番目の数値はグループに対して
    4番目の数値はその他に対して
    それぞれの権限を与える感じじゃないかな?

コメントを残す

*