这几天要给后台加一个记录操作日志的功能,可是项目已经开发完了不可能再去改以前的代码了,那有什么快捷的方法呢?

项目使用的ThinkPHP3.23 ,为了方便权限控制,后台控制器结构为:普通控制器 extends  pubController  ,pubController extends Controller.

所以,可不可以在pubController 里用__destruct 析构函数 记录日志呢?

  大家都知道,析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

  所以应该没问题咯,1、配置要记录日志的操作  2、读取IP、get、post数据写入库  3.本地测试没问题,搞定。

  

  结果  BU G T

  部署到线上之后,ThinkPHP底层报错了:

Fatal error: Uncaught Think\Exception: _STORAGE_WRITE_ERROR_***/Runtime/Data/_fields/表结构缓存文件.php in ***/Runtime/common~runtime.php:

Stack trace: # ***/ThinkPHP/Library/Think/Storage/Driver/File.class.php(): E('_STORAGE_WRITE_...') # [internal function]: Think\Storage\Driver\File->put('***', 'a:9:{i:0;s:2:"i...', 'F') #

***/ThinkPHP/Library/Think/Storage.class.php(): call_user_func_array(Array, Array) #

***/hwApp/Runtime/common~runtime.php(): Think\Storage::__callstatic('put', Array) #

***/ThinkPHP/Library/Think/Model.class.php(): F('***', Array) #

***/ThinkPHP/Library/Think/Model.class.php(): Think\Model->flush() #

***/ThinkPHP/Library/Think/Model.class.php(): Think\Model->_checkTableInfo() #

***/ThinkPHP/Library/Think/Model.class.php(): Think\Model->db(, '', true) #

***/Runtime/common~runtime.php(): Think\Model->__construct( in ***/Runtime/common~runtime.php on line 1

  咦?啥情况,难道没权限?

chmod  -R  Runtime 

还报错,难道是缓存引起的?

rm -rf Runtime

还报错。

最后在重新看官方对该函数的说明,手册里有一个不太明显的notice:

Note:

析构函数在脚本关闭时调用,此时所有的HTTP头信息已经发出。 脚本关闭时的工作目录有可能和在SAPI(如apache)中时不一样。

<?php
//获取当前工作目录
function __destruct(){
  echo getcwd();  //结果为根目录
}

  知道了问题所在,怎么解决呢?

1、在__destruct 中使用绝对路径操作文件

2、__destruct 之前比如构造函数内,先获取 getcwd() 工作目录,然后在 __destruct 中使用 chdir($StrPath)  重新设定工作目录。 //暂未测出有其他影响

  

  另:脚本关闭是指:代码执行完毕或者手动exit/die。若该对象的所有引用被删除则不会触发上述情况。

  

<?php
//在使用Thinkphp3.23框架开发时发现下面3个Action(实现功能其实都一样):只有aAction会触发上述情况(使用了exit die等)。
//原因:TP会删除对该对象的引用(非手动 调用控制器的变量为App::exec()内局部变量,会在执行完之后自动销毁)。
function aAction(){
 if(true){
      //doSomeThing;
      exit;
}
//doElseSomeThing;
}
function bAction(){
 if(true){
      //doSomeThing;
      return ;
}
//doElseSomeThing;
}
function cAction(){
  if(true){
    //doSomeThing;
  }else{
//doElseSomeThing;
  }
}

destruct析构函数里操作文件出现的问题的更多相关文章

  1. Win64 驱动内核编程-5.内核里操作文件

    内核里操作文件 RING0 操作文件和 RING3 操作文件在流程上没什么大的区别,也是"获得文件句柄->读/写/删/改->关闭文件句柄"的模式.当然了,只能用内核 A ...

  2. Java 操作jar包工具类以及如何快速修改Jar包里的文件内容

    需求背景:写了一个实时读取日志文件以及监控的小程序,打包成了Jar包可执行文件,通过我们的web主系统上传到各个服务器,然后调用ssh命令执行.每次上传前都要通过解压缩软件修改或者替换里面的配置文件, ...

  3. 从码云把之前的代码git push 回IDEA 对IDEA里的文件进行简单操作

    前情提要:我的IDEA里的项目之前已经和码云连接成功可以上传.但我直接在电脑文件夹里对文件进行重命名.剪切.粘贴等操作之后IDEA对操作后的文件不识别,无奈之下我将码云上之前的代码推回重新新建了项目. ...

  4. SQL Server里的文件和文件组

    在今天的文章里,我想谈下SQL Server里非常重要的话题:SQL Server如何处理文件的文件组.当你用CREATE DATABASE命令创建一个简单的数据库时,SQL Server为你创建2个 ...

  5. Eclipse点击工程结构里任意文件或文件夹变拖动(或复制)的bug

    本文为原创文章,欢迎转载,但请注明出处http://www.cnblogs.com/yexiubiao/p/5204601.html,未在文章页面明显位置给出原文连接的,将保留追究法律责任的权利. 在 ...

  6. 【菜鸟玩Linux开发】在C++里操作MySQL

    MySQL是一个的开源关系型数据库,对于服务端开发来说是一个优秀的选择.本篇内容将介绍如何在C++程序里操作MySQL数据库. ———————————————————————————————————— ...

  7. 操作文件方法简单总结(File,Directory,StreamReader,StreamWrite )

    对于文件夹,文档的操作一直处于一知半解状态,有时间闲下来了,好好练习了一把,对文档,文件的操作有了一个基本的认知, 若要深入了解,还是得通过实际的项目才行了,好了废话不多说,上酸菜!! 注:红色标题为 ...

  8. C#操作文件夹及文件的方法的使用

    本文收集了目前最为常用的C#经典操作文件的方法,具体内容如下:C#追加.拷贝.删除.移动文件.创建目录.递归删除文件夹及文件.指定文件夹下面的所有内容copy到目标文件夹下面.指定文件夹下面的所有内容 ...

  9. Java NIO Path接口和Files类配合操作文件

    Java NIO Path接口和Files类配合操作文件 @author ixenos Path接口 1.Path表示的是一个目录名序列,其后还可以跟着一个文件名,路径中第一个部件是根部件时就是绝对路 ...

随机推荐

  1. 微信小程序中转义字符的处理

    在微信小程序开发过程中,有时候会用到常用的一些特殊字符如:‘<’.‘>’.‘&’.‘空格’等,微信小程序同样支持对转义字符的处理,下面提供两种方法用来处理微信小程序中转义字符的处理 ...

  2. 『集群』003 Slithice 最简分布式(多个客户端,一个独立服务端)

    Slithice 最简分布式(多个客户端,一个独立服务端) 案例Demo 展示: 我们搭建一个 可以 独立运行 的 服务端:然后 多个客户端 并发链接 这个 服务端 完成 分布式逻辑: 服务器 独立运 ...

  3. 分析 js构造函数:对象方法 、类方法 、原型方法

    构造函数方法有对象方法.类方法.原型方法,这些方法在什么时候可以调用,什么时候不能调用,为什么? function Func(name){ this.name=name; this.ff=functi ...

  4. C#列表页面

    前台页面: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Index.aspx ...

  5. WPF ResourceDictionary 主题资源替换(一)

    当我们需要在程序中替换主题,更换另一套背景.颜色.样式时,如何在不修改资源Key值,直接替换呢? 问题&疑问 1. Key值冲突 同一ResourceDictionary中,不可以使用相同Ke ...

  6. Concat

    .net 对List使用Concat newlist=list.Concat(list2).ToList() JS的Concat则不用ToList(),一样要用个值去接 Concat返回是一个新数组, ...

  7. 学JAVA第十七天,接口与抽象方法

    JAVA接口可以让代码更加有合理的规范性,就想一个项目小组,组长要负责把成员的代码整合,但是每个成员写的方式都是按照他们自己的想法来写的, 所以,整合起来就非常麻烦. 但是,如果我们的组长制作了一个接 ...

  8. python 自定义模块的发布和安装

    [学习笔记] 自定义模块 使用的是pycharm 说白了就是.py文件都可以作为模块导入,像定义一个文件 名字为Mycode __all__ = ["add","sub& ...

  9. 安装odoo小程序商城模块报错 KeyError: u'oejia_weshop'

    错误截图如下 检查模块目录名是否不是 oejia_weshop,比如 oejia_weshop-master,注意odoo的模块名不能随便更改,odoo小程序商城模块目录名必须是oejia_wesho ...

  10. shell 查找与替换

    grep sed 如果想把一个字符串中的一些字符删除可以如此:#Echo “2006-11-21 22:16:30” | sed ‘s/-//g’ | sed ‘s/ //g’ | sed ‘s/:/ ...