ぷるぷるの雑記

低レイヤーがんばるぞいなブログ. 記事のご利用は自己責任で.

プログラミングでは一般的すぎる名前を使わない方が良い

タイトルの通り、プログラミングにおいて一般的すぎる名前をファイル名やクラス名にすると痛い目に合うかもしれません. 自分が経験した例を2つ紹介します.

PHPの例

Windows(xampp)において、index.phpから同ディレクトリ中のtable.phpというファイルをrequireしました.

// フォルダ構成
Project/-------- index.php
            ¦
             --- table.php

// index.php
<?php
   require("table.php");


Apache起動後、このサイトにブラウザでアクセスすると以下のようなエラーメッセージが.

Fatal error: Uncaught Error: Failed opening required 'HTML/Common.php' (include_path='C:\xampp\php\PEAR') in C:\xampp\php\pear\Table.php:68 Stack trace: #0 C:\xampp\htdocs\table\index.php(2): require() #1 {main} thrown in C:\xampp\php\pear\Table.php on line 68


エラーメッセージから察するに、pearフォルダ内にあるTable.phpを参照してしまってますね. どうやらphpのrequireやincludeはライブラリ内のファイルを参照し、そのあとで作業ディレクトリ内を参照するようです.


解決策はいろいろあると思いますが、次の2つが真っ先に思い浮かびました.

  1. 取り込むファイル名を意味が通る範疇で変更する(tbl.phpなど)
  2. requireのパスを./table.php のようにする


普段からパスを意識しろってことですね. ちなみに、phpのインクルードパスはphp.iniに定義されています.

// php.ini一部抜粋

;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;

; UNIX: "/path1:/path2"
include_path=C:\xampp\php\PEAR
;
; Windows: "\path1;\path2"
;include_path = ".;c:\php\includes"
;
; PHP's default setting for include_path is ".;/path/to/php/pear"
; https://php.net/include-path

; The root of the PHP pages, used only if nonempty.
; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root
; if you are running php as a CGI under any web server (other than IIS)
; see documentation for security issues.  The alternate is to use the
; cgi.force_redirect configuration below
; https://php.net/doc-root
doc_root=

; The directory under which PHP opens the script using /~username used only
; if nonempty.
; https://php.net/user-dir
user_dir=

; Directory in which the loadable extensions (modules) reside.
; https://php.net/extension-dir
;extension_dir = "./"
; On windows:
extension_dir="C:\xampp\php\ext"

; Directory where the temporary files should be placed.
; Defaults to the system default (see sys_get_temp_dir)
;sys_temp_dir = "/tmp"

; Whether or not to enable the dl() function.  The dl() function does NOT work
; properly in multithreaded servers, such as IIS or Zeus, and is automatically
; disabled on them.
; https://php.net/enable-dl
enable_dl=Off

; cgi.force_redirect is necessary to provide security running PHP as a CGI under
; most web servers.  Left undefined, PHP turns this on by default.  You can
; turn it off here AT YOUR OWN RISK
; **You CAN safely turn this off for IIS, in fact, you MUST.**
; https://php.net/cgi.force-redirect
;cgi.force_redirect = 1

; if cgi.nph is enabled it will force cgi to always sent Status: 200 with
; every request. PHP's default behavior is to disable this feature.
;cgi.nph = 1

; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape
; (iPlanet) web servers, you MAY need to set an environment variable name that PHP
; will look for to know it is OK to continue execution.  Setting this variable MAY
; cause security issues, KNOW WHAT YOU ARE DOING FIRST.
; https://php.net/cgi.redirect-status-env
;cgi.redirect_status_env =

; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec.  A setting
; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; https://php.net/cgi.fix-pathinfo
;cgi.fix_pathinfo=1

; if cgi.discard_path is enabled, the PHP CGI binary can safely be placed outside
; of the web tree and people will not be able to circumvent .htaccess security.
;cgi.discard_path=1

; FastCGI under IIS supports the ability to impersonate
; security tokens of the calling client.  This allows IIS to define the
; security context that the request runs under.  mod_fastcgi under Apache
; does not currently support this feature (03/17/2002)
; Set to 1 if running under IIS.  Default is zero.
; https://php.net/fastcgi.impersonate
;fastcgi.impersonate = 1

; Disable logging through FastCGI connection. PHP's default behavior is to enable
; this feature.
;fastcgi.logging = 0

; cgi.rfc2616_headers configuration option tells PHP what type of headers to
; use when sending HTTP response code. If set to 0, PHP sends Status: header that
; is supported by Apache. When this option is set to 1, PHP will send
; RFC2616 compliant header.
; Default is zero.
; https://php.net/cgi.rfc2616-headers
;cgi.rfc2616_headers = 0

; cgi.check_shebang_line controls whether CGI PHP checks for line starting with #!
; (shebang) at the top of the running script. This line might be needed if the
; script support running both as stand-alone script and via PHP CGI<. PHP in CGI
; mode skips this line and ignores its content if this directive is turned on.
; https://php.net/cgi.check-shebang-line
;cgi.check_shebang_line=1

VC++の例

Visual Studio 2017においてPictureというクラスを自分で定義すると、Pictureというstruct型が既にありビルドが通りませんでした. 「すべての Visual C++ ディレクトリ」において「struct Picture」で検索すると一件だけ引っ掛かりました. どうやらこいつのせいでPictureという型の再定義が生じてしまっていたようです.

すべて検索 "struct picture", サブ フォルダー, 検索結果 1, "すべての Visual C++ ディレクトリ", ""
  C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\comdef.h(506):    struct Picture : IPictureDisp {};


これに関してはcomdef.hをインクルードしないというわけにもいかないので、CPictureクラスにリネームすることで事なきを得ました.

まとめ

エラーの内容が唐突ですが、一度この手の罠にはまったことがあれば解決までに時間はかからないと思います. 予約語をすべて覚えることは無理なので、エラーに出くわしたときに対策できれば十分でしょう.