「realpath」と「__FILE__」の違いは、シンボリックリンクを評価するかどうかだけ? – php

質問:


Q1.realpath__FILE__の共通点
・何れも「サーバのファイルシステム上の絶対パス」を返すのでしょうか?

・「正規化された絶対パス名」の意味が理解できません。シンボリックリンクの元の位置、という意味?


Q2.realpathの使い所が分からないのですが、
・シンボリックリンクを使用していない場合は、全て「__FILE__」で代用できるでしょうか?


Q3.組み合わせについて
・そもそも、realpathは単独で使用するもの?
・それとも「__FILE__」と併用するもの?
・あるいはどちらでも良い??


Q4.例えばですが

・下記例は常に同じ結果となりますか?
・「__FILE__」で既に「正規化された絶対パス」を返しているので、その上でさらにrealpathを行う意味はない?
・「正規化された絶対パス」をさらに「正規化された絶対パス」処理してもエラーとはならない?
・単なる無駄な処理?

include( realpath( dirname( __FILE__ ) ).'/a/b.php' );
include( ( dirname( __FILE__ ) ).'/a/b.php' );

質問者: re9

OOPer

Q1.realpathと__FILE__の共通点

・何れも「サーバのファイルシステム上の絶対パス」を返すのでしょうか?

はい。

・「正規化された絶対パス名」の意味が理解できません。シンボリックリンクの元の位置、という意味?

シンボリックリンクの元の位置に変換することも含まれますが、それだけではありません。きちんと理解するには、Unixのファイルシステムでのパス名の表し方に冗長性(余計なものを挟み込んで長ったらしく書くことができる)があると言うことを理解しておかないといけません。

例えば、次のようなディレクトリ構成でファイルが配置されているとします。

/var/
    www/
        php/
            common/
                utils.php
            pages/
                home/
                    index.php

この時、utils.phpindex.phpの中からアクセスする場合、/var/www/php/common/utils.phpのような絶対パスで指定せずに、index.phpの存在するディレクトリからの相対パスで、../../common/utils.phpと表すことがあるのはご存知かと思います。

相対パスは基準になる位置が変わってしまうと意味が変わってしまいますから、システム側(この場合PHPの中の何か)は、手っ取り早く絶対パスを作るためにこんな表現を作ることがあります。

/var/www/php/pages/home/../../common/utils.php

Unix型のファイルシステムを今すぐ試せる環境があれば、このような..を含むパスを指定しても普通にそのファイルにアクセスできることがわかります。

これは便利な機構ではあるのですが、使い方によっては不便になる時があります。例えば、現在のPHPの処理系はよく使うファイルをキャッシュしてメモリに保持できるようになっているわけですが(*)、単純な文字列でパスを比較して/var/www/php/common/utils.php/var/www/php/pages/home/../../common/utils.phpとは違うファイルなんだと判定されると、既にutils.phpはメモリに読み込んであるのに、また同じものをメモリに保持してしまうことになります。

そこでそのような用途のために「パスを表す文字列ではこれが正しい形」と言うのを決めてやり、その正しい形に変換することを「正規化する」と言うわけです。

上記の例でいうと、/var/www/php/common/utils.php/var/www/php/pages/home/../../common/utils.phpとはどちらも有効な「絶対パス」ですが、「正規化された絶対パス」としては、/var/www/php/common/utils.phpだけを表すことになります。ちなみに「パス」のことを「パス名」と言うのは古いUnixでの習慣くらいに思って「名」は無視してください。(英語でもpathとpath nameは同義に使います。)

当然ながら、シンボリックリンクはリンクじゃない元の位置のパスに置き換え、../..などの冗長な表現は省いた形が正規化された形(正規形)です。

※Unixのファイルパス以外の話をしている場合、「正規化」は全然違うことを表しますが、ものすごぉく大きな立場から見ると同じような概念を表していると言って良いでしょう。
(*) 実際にPHPに標準搭載のキャッシュ機能はもっと複雑です。「PHPのキャッシュ機能」について学習を進められる場合、ここに書かれた説明は単なるたとえ話でPHPのキャッシュ機能そのものを説明しているのではないことにご注意ください。


Q2.realpathの使い所が分からないのですが、

・シンボリックリンクを使用していない場合は、全て「__FILE__」で代用できるでしょうか?

できません。

そもそもrealpathは関数で、__FILE__は定義済み擬似定数で用途が異なります。

先の例のindex.phpの中では、__FILE__の値は'/var/www/php/pages/home/index.php'という文字列になりますし、utils.phpの中では'/var/www/php/common/utils.php'という文字列になります。

一方realpathの方は関数ですから、パスを表す文字列を引数として使うことになります。例えばrealpath('/var/www/php/pages/home/../../common/utils.php')の結果は'/var/www/php/common/utils.php'という正規化された絶対パスになります。

かなり上の方で書いたように、実際のファイルシステム的には..なんかの冗長な表現が含まれていても大抵は動くのですが、「なんか気持ち悪い」「もしかして不具合が出るかも」程度の理由で、文字列からファイルパスを作ったりした後にrealpathが使われている場合も多いです。


Q3.組み合わせについて

・そもそも、realpathは単独で使用するもの?
・それとも「__FILE__」と併用するもの?

上記のようにrealpathは関数ですから、単独で使用することはありません。ただし、組み合わせられる(引数として渡される)のは__FILE__ではなく、__DIR__かもしれませんし、そんな擬似定数以外の文字列式かもしれません。

・あるいはどちらでも良い??

それぞれ目的も使い方もちがうので、「どちらでも良い」なんてことはありません。目的・用途によって正しく使い分けてください。


Q4.例えばですが

・下記例は常に同じ結果となりますか?

(Unix互換のファイルシステムを使用しているとして)はい。

※実用レベルのOSで同じ結果にならないようなファイルシステムを採用している例や、どんなファイルシステムにしたら同じ結果にならないようにできるかと言うのは思いつきませんが、絶対にそんなものはありえないと断言はできません。ただ、通常のPHPを動作させる環境で夢のような別OSを想定しても仕方ないので、以下では上記の仮定が成り立つものとします。

・「__FILE__」で既に「正規化された絶対パス」を返しているので、その上でさらにrealpathを行う意味はない?

書かれている処理がrealpath(__FILE__)なら即YESですね。realpath( dirname( __FILE__ ) )についても、正規化されたパスを与えられた時にdirname()の結果が正規化されていないことは考えられないので、最初の仮定の下YESです。

・「正規化された絶対パス」をさらに「正規化された絶対パス」処理してもエラーとはならない?

なりません。必ず元のパスと同じ文字列が得られます。

・単なる無駄な処理?

ご掲載の2行のコードだけを見るなら、上の方は「無駄な処理」をしています。

ただ、かっこの位置を少し変えて、

include( realpath( dirname( __FILE__ ).'/a/b.php' ) );

とするなら、少しは意味があるかもしれません。あちこちにこの行がコピペされて使い回されていく間に'/a/b.php'の部分は他のパスや変数に置き換わる可能性もあるでしょうから、この回答の Q2 末尾に書かせてもらったように、その辺も考えて「文字列からファイルパスを作ったりした後に」必ずrealpathをかませる、と言うのであれば、特定の場合には無駄でも意味があるコーディングスタイルと言えるでしょう。

しかしながら、ご掲載のように、

include( realpath( dirname( __FILE__ ) ).'/a/b.php' );

の場合だと、せっかくrealpath( dirname( __FILE__ ) )で確実に(実は無駄ですが)正規化しているのに、その後文字列演算で違うパスを作ってしまっています。「なんとなく」で理由もわからずにrealpathを使っているのか?と言う気がします(*)。最初に書いた結論通りですが、「無駄な処理」です。

(*) __FILE__の変更履歴に「4.0.2 __FILE__ に常に絶対パスを含め、シンボリックリンクも解決するようになりました。 これより前のバージョンでは、場合によっては相対パスが含まれていることもありました。」と言う記載がある(ちなみに私がPHPを触り始めるより遥か以前の変更です)ので、古い古いPHPの頃にそんな書き方が身についた人のコード(あるいはそう言うコードを真似ただけのコード)なのかもしれません。

出典

Related Posts:

amazonの価格取得 – javascript php api
質問: 、amazonの個別商品ページのURL(例)http://www.amazon.co.jp/dp/4822242633 を使って、商品価格だけを抜き出す場合、いろいろとやり方はあると思いますが、皆さんならどのように実現されますでしょうか。 教えて頂けますと、幸いです。 ※言語はPHPでお願いいたします。 ※amazon apiはリクエスト制限があるので、amazon api以外でお願いいたします。 ※商品価格とは以下のタグの部分です。 <span class="a-size-medium a-color-price offer-price a-text-normal">¥ 2,376</span> よろしくお願いいたします。 質問者: rei0328 <?php $html = file_get_contents("http://www.amazon.co.jp/dp/4822242633"); $dom = new DOMDocument(); @$dom->loadHTML($html); $xml = simplexml_import_dom($dom); $ret = $xml->xpath('//span[@class="a-size-medium a-color-price offer-price ...
phpの値にcssを反映したい – php css
質問: phpで変数が入った値にcssを反映させ、変数に入った画像ファイルの出力位置を変更したいのですが、なぜか以下コードでは反映されません。 どなたか、アドバイス頂ければ幸いです。 上記変数の中には5枚のトランプの画像が格納されています。 以下は、phpのコードです。 "<div class='player1_cards'>".$player1."</div>"; "<div class='player2_cards'>".$player2."</div>"; <css> .player1_cards{ background:#fff888; height:100px; position:absolute; top:50%; ...
MediaWikiで作成記事が文字化けする – php mysql api
質問: MediaWikiで新しい記事を作成する際に、記事の本文が文字化けして表示されます。 タイトル文章は正しく表示され、MySQLにも日本語で保存されていることは確認しました。 また、ブラウザの設定よりJavascriptを切って記事の編集を行いましたが文字化けは解消されませんでした。 現在の環境は以下のとおりです。 OS:CnetOS6.8 DB:mysql Ver 14.14 Distrib 5.7.16, for Linux (x86_64) using EditLine wrapper ※使用する文字コードの設定はUTF-8 PHP:5.6.27 MediaWiki:1.27 ブラウザ:Chrome 54.0.2840.71 よろしくお願いします。 質問者: codeZ Laclip 既に自己解決されているようですが、mbstring.http_inputはPHP 5.6.0 で非推奨になっているようです。 mbstring.http_inputの編集はdefault_charsetやinput_encodingを編集しても反応しない時の方がいいでしょう。 ...
PHPで変数に変数を代入した時に反映されない – php
質問: 変数animalsにHTMLの雛形を作っておいて、ホイールした時に雛形内の変数を反映させたいです。 構文 if(x == 0) { $animals = '<div>' . $lion . '</div>'; for($i=0; $i<5; $i++) { ...
変数の値が増えたか減ったかの判定方法 – javascript swift php
質問: Swiftで実装したいのですがロジックが応用できればどんな言語でも構いません。とある変数の値(数字)が動的に変わるのですが、その変数の値が増えたのか減ったのかで処理を分岐させたいと思っています。コードは下記のような感じです。 if(変数の値が増えた){ print("変数の値が増えた!") }esle if(いや、変数の値が減った){ print("変数の値が減った!") } 実装の方法が思いつきません。アドバイスいただければ幸いです 質問者: ryosuke-hujisawa 変更前の値と変更後の値を配列にとって配列の最初と最後を比較することで解決しました 出典
PHP多次元配列から階層リストタグを出力したい – php html
質問: 元データhogeAry ・子に対する親を parent_id で指定 ・親は parent_id = 0 Array ( => Array ( ...
phpでmysqlにデータを保存しているデータをid毎に静的フアィルhtmlに生成して書き出したいです – php mysql
質問: phpでmysqlデータベースに test_id, test_title, test_contents, test_date.test_imageのデータを保存しています。このデータのid毎に静的htmlに生成して書き出したいです。WordPressやMovable Typeの静的ファイルの書き出すとかに似ているイメージです。 例えば:上記添付した画像(CMS.png)の書き出すボタンを押すと添付した画像(database.png)から、/Applications/MAMP/htdocs/test/のディレクトリーの下に静的htmlファイにて生成して書き出したいです /Applications/MAMP/htdocs/test/1.html /Applications/MAMP/htdocs/test/2.html 1.htmlと2.htmlにはデータベースに保存されているtest_id, test_title, test_contents, test_date.test_imageのデータ内容がそれぞれのhtmlに全部表示されるようにしたいです これはphpや何かをして書き出すことは可能でしょうか? ご教授お願い致します。 @D.T さん sync.phpファイルは下記です。 <?php //require_once("db.php"); // 取得するIDをURLパラメータから取得 if (!isset($_GET)) { ...
CakePHPでSet::mergeを使ってcssファイルを統合する – php cakephp
質問: 業務であるアプリケーションのapp/View/Layoutsにあるソースコードをみていると以下のようにしてcssファイルを一つにまとめていました。 <?php $css_files = array( CSS . 'bootstrap.less', CSS . 'jquery-ui-1.10.3.custom.css', CSS . 'fullcalendar.css', ...
ボタンの読込先を個別に管理したい – php
質問: こんにちは require_onceでクラスを読み込めると思うのですが、 require_onceが多数あるとどれか一個を読み込ませることはできませんよね。 例えば、 require_once(DIR . '/functions.php'); ①require_once(DIR . '/autoload3.php'); ②require_once(DIR . '/autoload2.php'); このようになっていたとします。 (A)あるリンクの際には②を読み込んでほしい(①は読み込む必要がない) (B)あるリンクの際には①を読み込んでほしい(②は読み込んで欲しくない) こういった時(A)を行うとエラーが出てしまいます。 どうすればいいんでしょうか?? 質問者: Kosuke Yamamoto PHPでは、どのアドレスで呼ばれたか(またはパラメータに何が指定されたか)が分かるので、 それを使ってif文で分ければ良いのではないでしょうか。 if ($_SERVER == 'Aのアドレス') require_once(DIR . '/autoload2.php'); else ...
PHPでhrefの値の置換 – php html 正規表現
質問: 以下のようなhtmlがあり、その中のhrefの値を全て、$urlに置換するにはどのような処理を行えばいいでしょうか? 詳しい方、ご教示ください。宜しくお願い致します。 <div class="article_image"><a href="http://www.amazon.co.jp/PENTAX-%E3%83%9F%E3%83%A9%E3%83%BC%E3%83%AC%E3%82%B9%E4%B8%80%E7%9C%BC-%E3%82%BA%E3%83%BC%E3%83%A0%E3%83%AC%E3%83%B3%E3%82%BA%E3%82%AD%E3%83%83%E3%83%88-STANDARD-06239/dp/B00MFD07OO/ref=sr_1_1/375-7893352-7638937?ie=UTF8&qid=1457086894&sr=8-1&keywords=Q-S1"><img class="article_img" src="http://ecx.images-amazon.com/images/I/41Rs3BwRg2L._AA160_.jpg" /></a></div><div class="article_image_text article_product_info"><p class="article_product_brand"><a href="http://www.amazon.co.jp/PENTAX-%E3%83%9F%E3%83%A9%E3%83%BC%E3%83%AC%E3%82%B9%E4%B8%80%E7%9C%BC-%E3%82%BA%E3%83%BC%E3%83%A0%E3%83%AC%E3%83%B3%E3%82%BA%E3%82%AD%E3%83%83%E3%83%88-STANDARD-06239/dp/B00MFD07OO/ref=sr_1_1/375-7893352-7638937?ie=UTF8&qid=1457086894&sr=8-1&keywords=Q-S1">PENTAX ミラーレス一眼 Q-S1 ズームレンズキット ゴールド 06239</a></p><p class="article_product_price">¥ 28,205 </p><div class="btn_item_area clearfix"><a ...
ajaxが動作しない – javascript php ajax
質問: 以下のajaxが動作しないのですが、原因がわかる方いらしゃいますでしょうか。 <!DOCTYPE html> <html> <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#"> <body> <form method="post" action="" ...
aタグにonclickの挿入 – javascript php html
質問: <a href="example.com" class="a"> 上記のようなaタグに正規表現を使用して、onclickイベントを追加したいと考えています。 どのようにすればうまくいきますでしょうか。 詳しい方、ご教示ください。宜しくお願い致します。 質問者: rei0328 正規表現ではありませんがquerySelectorAll関数を利用するとこんな感じでしょうか。 function someFunction(event) { console.log(event); } var aList = document.querySelectorAll('a.a'); for (var i = 0; i < aList.length; ...
クーポンコードを使って割引率を決める – php
質問: クーポンコードを使って割引率を決めたいのですが、discount2.phpの46行目とdescountForm2.phpの40行目のエラー該当箇所を見ても解決方法がわかりません。 htdocsの中にsaledata.phpとdiscountForm2.phpとdiscount2.phpとutil.phpが並列して入っています。 どなたかご教示頂けると幸いです。宜しくお願いします。 エラーコード PHP Fatal error: Uncaught Error: Call to undefined function getCouponRate() in /Applications/MAMP/htdocs/discountForm2.php:40 Stack trace: #0 {main} thrown in /Applications/MAMP/htdocs/discountForm2.php on line ...
Twitter APIでTwitterアカウントのテーマカラーを変更するには?(PHP) – php api twitter
質問: TwitterのAPIを使ったPHPプログラムで、アカウントのテーマカラーを変更させようと、 $request = $connection->post("http://api.twitter.com/1.1/account/update_profile.json", array("profile_link_color" => "606090")); と書いたのですが、 object(stdClass)#3 (1) { => array(1) { => object(stdClass)#8 (2) { => string(31) "Sorry, that page does not exist" => ...
php offset 0 のときのview表示を0にしたい。 – php
質問: エラー表示Notice (8): Undefined offset: 0 のときに0を表示させたいのですが、 以下のコードのときにoffset 0の表示がでます。 <?php $rate = ($one / $two)*100; if ($rate == null) { ...

You Might Also Like

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です