Fatal error: session_start(): Failed to initialize storage module:

之前编译安装的LNMP环境+phpmyamdin4.02的版本,今天突然出现这个问题:Fatal error: session_start(): Failed to initialize storage module: files (path: ) in /data/www/phpmyadmin/libraries/session.inc.php on line 83

大致意思是session会话初始化的时候储存路径有误!第一反应就是查看php.ini的配置文件中的:session.save_path = "/tmp"

默认前面是加的分号,表示不启用,我之前配置的时候已经启用了,那为什么还会报错呢?,于是网上找了一些资料,感觉都千篇一律:

1、检查error.log(Apache2.2logs)文件,查看是否有错误报告,未发现。

2、检查php.ini中的session.save_handler的值是否为files,如果不是改为files

3、检查php.ini文件中session.save_path是否被注释了,如果有,则去掉前面的”;”。

4、将save_path后面的路径改成已有的路径,比如”D:phptemp”

5、检查temp文件夹的属性是否可读可写。

6、重启APACHE服务器。OK

不知道那些哥们转载的时候自己试过了没有(在这里喷一下,最讨厌那种自己都没有亲测,就一股脑的转来转去。一点都不负责!)根据上面的流程,排查了之后发现压根就没有解决,不过璞玉的服务器是nginx非apache。

然后自己写了一个脚本test.php:

$r = session_start(); var_dump($r);

打印结果为:

Warning: session_start(): SAFE MODE Restriction in effect. The script whose uid is 501 is not allowed to access /tmp owned by uid 0 in /data/www/test.php on line 3 Fatal error: session_start(): Failed to initialize storage module: files (path: ) in /data/www/test.php on line 3

意思是 php5一个安全模式的bug,默认session的save_path是系统的临时目录,这样会要校验权限。而这个脚本不能通过/tmp拥有者uid为0来执行uid是501也是www用户组的权限

解决这个有两种解决方法:

1。关闭安全模式;

2。在命令行下chown改文件/目录的拥有者

当然两种方法都要求你有服务器的权限,下面是璞玉php.ini的配置文件:

  1. [Session]
  2. ; Handler used to store/retrieve data.
  3. ; http://php.net/session.save-handler
  4. session.save_handler = files; Argument passed to save_handler. In the case of files, this is the path
  5. ; where data files are stored. Note: Windows users have to change this
  6. ; variable in order to use PHP's session functions.
  7. ;
  8. ; The path can be defined as:
  9. ;
  10. ; session.save_path = "N;/path"
  11. ;
  12. ; where N is an integer. Instead of storing all the session files in
  13. ; /path, what this will do is use subdirectories N-levels deep, and
  14. ; store the session data in those directories. This is useful if you
  15. ; or your OS have problems with lots of files in one directory, and is
  16. ; a more efficient layout for servers that handle lots of sessions.
  17. ;
  18. ; NOTE 1: PHP will not create this directory structure automatically.
  19. ; You can use the script in the ext/session dir for that purpose.
  20. ; NOTE 2: See the section on garbage collection below if you choose to
  21. ; use subdirectories for session storage
  22. ;
  23. ; The file storage module creates files using mode 600 by default.
  24. ; You can change that by using
  25. ;
  26. ; session.save_path = "N;MODE;/path"
  27. ;
  28. ; where MODE is the octal representation of the mode. Note that this
  29. ; does not overwrite the process's umask.
  30. ; http://php.net/session.save-path
  31. session.save_path = "/tmp"
  32. ; Whether to use cookies.
  33. ; http://php.net/session.use-cookies
  34. session.use_cookies = 1
  35. ; http://php.net/session.cookie-secure
  36. ;session.cookie_secure =
  37. ; This option forces PHP to fetch and use a cookie for storing and maintaining
  38. ; the session id. We encourage this operation as it's very helpful in combatting
  39. ; session hijacking when not specifying and managing your own session id. It is
  40. ; not the end all be all of session hijacking defense, but it's a good start.
  41. ; http://php.net/session.use-only-cookies
  42. session.use_only_cookies = 1
  43. ; Name of the session (used as cookie name).
  44. ; http://php.net/session.name
  45. session.name = PHPSESSID
  46. ; Initialize session on request startup.
  47. ; http://php.net/session.auto-start
  48. session.auto_start = 0
  49. ; Lifetime in seconds of cookie or, if 0, until browser is restarted.
  50. ; http://php.net/session.cookie-lifetime
  51. session.cookie_lifetime = 0
  52. ; The path for which the cookie is valid.
  53. ; http://php.net/session.cookie-path
  54. session.cookie_path = /
  55. ; The domain for which the cookie is valid.
  56. ; http://php.net/session.cookie-domain
  57. session.cookie_domain =
  58. ; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript.
  59. ; http://php.net/session.cookie-httponly
  60. session.cookie_httponly =
  61. ; Handler used to serialize data. php is the standard serializer of PHP.
  62. ; http://php.net/session.serialize-handler
  63. session.serialize_handler = php
  64. ; Defines the probability that the 'garbage collection' process is started
  65. ; on every session initialization. The probability is calculated by using
  66. ; gc_probability/gc_divisor. Where session.gc_probability is the numerator
  67. ; and gc_divisor is the denominator in the equation. Setting this value to 1
  68. ; when the session.gc_divisor value is 100 will give you approximately a 1% chance
  69. ; the gc will run on any give request.
  70. ; Default Value: 1
  71. ; Development Value: 1
  72. ; Production Value: 1
  73. ; http://php.net/session.gc-probability
  74. session.gc_probability = 1
  75. ; Defines the probability that the 'garbage collection' process is started on every
  76. ; session initialization. The probability is calculated by using the following equation:
  77. ; gc_probability/gc_divisor. Where session.gc_probability is the numerator and
  78. ; session.gc_divisor is the denominator in the equation. Setting this value to 1
  79. ; when the session.gc_divisor value is 100 will give you approximately a 1% chance
  80. ; the gc will run on any give request. Increasing this value to 1000 will give you
  81. ; a 0.1% chance the gc will run on any give request. For high volume production servers,
  82. ; this is a more efficient approach.
  83. ; Default Value: 100
  84. ; Development Value: 1000
  85. ; Production Value: 1000
  86. ; http://php.net/session.gc-divisor
  87. session.gc_divisor = 1000
  88. ; After this number of seconds, stored data will be seen as 'garbage' and
  89. ; cleaned up by the garbage collection process.
  90. ; http://php.net/session.gc-maxlifetime
  91. session.gc_maxlifetime = 1440
  92. ; NOTE: If you are using the subdirectory option for storing session files
  93. ; (see session.save_path above), then garbage collection does *not*
  94. ; happen automatically. You will need to do your own garbage
  95. ; collection through a shell script, cron entry, or some other method.
  96. ; For example, the following script would is the equivalent of
  97. ; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
  98. ; find /path/to/sessions -cmin +24 | xargs rm
  99. ; PHP 4.2 and less have an undocumented feature/bug that allows you to
  100. ; to initialize a session variable in the global scope, even when register_globals
  101. ; is disabled. PHP 4.3 and later will warn you, if this feature is used.
  102. ; You can disable the feature and the warning separately. At this time,
  103. ; the warning is only displayed, if bug_compat_42 is enabled. This feature
  104. ; introduces some serious security problems if not handled correctly. It's
  105. ; recommended that you do not use this feature on production servers. But you
  106. ; should enable this on development servers and enable the warning as well. If you
  107. ; do not enable the feature on development servers, you won't be warned when it's
  108. ; used and debugging errors caused by this can be difficult to track down.
  109. ; Default Value: On
  110. ; Development Value: On
  111. ; Production Value: Off
  112. ; http://php.net/session.bug-compat-42
  113. session.bug_compat_42 = Off
  114. ; This setting controls whether or not you are warned by PHP when initializing a
  115. ; session value into the global space. session.bug_compat_42 must be enabled before
  116. ; these warnings can be issued by PHP. See the directive above for more information.
  117. ; Default Value: On
  118. ; Development Value: On
  119. ; Production Value: Off
  120. ; http://php.net/session.bug-compat-warn
  121. session.bug_compat_warn = Off
  122. ; Check HTTP Referer to invalidate externally stored URLs containing ids.
  123. ; HTTP_REFERER has to contain this substring for the session to be
  124. ; considered as valid.
  125. ; http://php.net/session.referer-check
  126. session.referer_check =
  127. ; How many bytes to read from the file.
  128. ; http://php.net/session.entropy-length
  129. session.entropy_length = 0
  130. ; Specified here to create the session id.
  131. ; http://php.net/session.entropy-file
  132. ; On systems that don't have /dev/urandom /dev/arandom can be used
  133. ; On windows, setting the entropy_length setting will activate the
  134. ; Windows random source (using the CryptoAPI)
  135. ;session.entropy_file = /dev/urandom
  136. ; Set to {nocache,private,public,} to determine HTTP caching aspects
  137. ; or leave this empty to avoid sending anti-caching headers.
  138. ; http://php.net/session.cache-limiter
  139. session.cache_limiter = nocache
  140. ; Document expires after n minutes.
  141. ; http://php.net/session.cache-expire
  142. session.cache_expire = 180
  143. ; trans sid support is disabled by default.
  144. ; Use of trans sid may risk your users security.
  145. ; Use this option with caution.
  146. ; - User may send URL contains active session ID
  147. ; to other person via. email/irc/etc.
  148. ; - URL that contains active session ID may be stored
  149. ; in publically accessible computer.
  150. ; - User may access your site with the same session ID
  151. ; always using URL stored in browser's history or bookmarks.
  152. ; http://php.net/session.use-trans-sid
  153. session.use_trans_sid = 0
  154. ; Select a hash function for use in generating session ids.
  155. ; Possible Values
  156. ; 0 (MD5 128 bits)
  157. ; 1 (SHA-1 160 bits)
  158. ; This option may also be set to the name of any hash function supported by
  159. ; the hash extension. A list of available hashes is returned by the hash_algos()
  160. ; function.
  161. ; http://php.net/session.hash-function
  162. session.hash_function = 0
  163. ; Define how many bits are stored in each character when converting
  164. ; the binary hash data to something readable.
  165. ; Possible values:
  166. ; 4 (4 bits: 0-9, a-f)
  167. ; 5 (5 bits: 0-9, a-v)
  168. ; 6 (6 bits: 0-9, a-z, A-Z, "-", ",")
  169. ; Default Value: 4
  170. ; Development Value: 5
  171. ; Production Value: 5
  172. ; http://php.net/session.hash-bits-per-character
  173. session.hash_bits_per_character = 5
  174. ; The URL rewriter will look for URLs in a defined set of HTML tags.
  175. ; form/fieldset are special; if you include them here, the rewriter will
  176. ; add a hidden <input> field with the info which is otherwise appended
  177. ; to URLs. If you want XHTML conformity, remove the form entry.
  178. ; Note that all valid entries require a "=", even if no value follows.
  179. ; Default Value: "a=href,area=href,frame=src,form=,fieldset="
  180. ; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
  181. ; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
  182. ; http://php.net/url-rewriter.tags
  183. url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"

因为这个是在一台VPS上面配置的,上面有多个项目,于是璞玉打开一个项目,发现此项,,目的验证码功能是OK的,于是查看代码如下:

  1. $sessSavePath = "/data/sessions/";
  2. // Session保存路径
  3. if(is_writeable($sessSavePath) && is_readable($sessSavePath)){ session_save_path($sessSavePath); }
  4. if(!emptyempty($cfg_domain_cookie)) session_set_cookie_params(0,'/',$cfg_domain_cookie);

上面这个代码是在session_start() 初始化之前来判断是否存在session会话的文件夹,于是就在phpmyadmin里面的保存的那个文件/phpmyadmin/libraries/session.inc.php做了下修改:

  1. if (! isset($_COOKIE[$session_name])) {
  2. // on first start of session we check for errors
  3. // f.e. session dir cannot be accessed - session file not created
  4. $orig_error_count = $GLOBALS['error_handler']->countErrors();
  5. //session_save_path('./tmp');
  6. session_save_path("/data/www/session");
  7. $r = session_start();
  8. if ($r !== true
  9. || $orig_error_count != $GLOBALS['error_handler']->countErrors()
  10. ) {
  11. setcookie($session_name, '', 1);
  12. /*
  13. * Session initialization is done before selecting language, so we
  14. * can not use translations here.
  15. */
  16. PMA_fatalError('Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly. Also ensure that cookies are enabled in your browser.');
  17. }
  18. unset($orig_error_count);
  19. } else {
  20. session_save_path("/data/www/session");
  21. session_start();
  22. }

在 session_start(); 前面添加了 session_save_path(“/data/www/session”); 就解决了这个问题,切记通过@ini_set(‘session.save_path’, ”/data/www/session”);无效!

这个问题困扰了我几个小时,终于解决了,所以就记录下来,对日后应该会有帮助.