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

项目使用的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. 使用docker-compose 大杀器来部署服务 上(转)

    使用docker-compose 大杀器来部署服务 上 我们都听过或者用过 docker,然而使用方式却是仅仅用手动的方式,这样去操作 docker 还是很原始. 好吧,可能在小白的眼中噼里啪啦的对着 ...

  2. CSS揭秘—透明边框(一)

    前言: 所有实例均来自<CSS揭秘>,该书以平时遇到的疑难杂症为引,提供解决方法,只能说秒极了,再一次刷新了我对CSS的认知 该书只提供了关键CSS代码,虽然有在线示例代码链接,但访问速度 ...

  3. .Net MVC+NPOI实现下载自定义的Word文档

    我们浏览很多网站时都会看到下载文件的功能(图片.word文档等),好巧不巧的是贫道近日也遇到了这个问题,于是写一篇博客记录一下. 技术点:MVC.NPOI.Form表单. 具体如何实现,待贫道喝一口水 ...

  4. Java数据结构和算法 - OverView

    Q: 为什么要学习数据结构与算法? A: 如果说Java语言是自动档轿车,C语言就是手动档吉普.数据结构呢?是变速箱的工作原理.你完全可以不知道变速箱怎样工作,就把自动档的车子从1档开到4档,而且未必 ...

  5. 【Android Studio安装部署系列】十六、Android studio在layout目录下新建子目录

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 一般用于分类显示不同模块的layout布局文件. 在res/layout文件夹下创建子目录 res/layout鼠标右键——New— ...

  6. 高效并发JUC锁-砖石

    JUC包的锁(可重入锁和读写锁) Lock是JAVA5增加的内容,在JUC(java.util.concurrent.locks)包下面,作者是并发大师Doug Lea.JUC包提供了很多封装的锁,包 ...

  7. [翻译] 介绍EF Core

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  8. axios(封装使用、拦截特定请求、判断所有请求加载完毕)

    博客地址:https://ainyi.com/71 基于 Promise 的 HTTP 请求客户端,可同时在浏览器和 Node.js 中使用 vue2.0之后,就不再对 vue-resource 更新 ...

  9. 深入理解 Python 中的上下文管理器

    提示:前面的内容较为基础,重点知识在后半段. with 这个关键字,对于每一学习Python的人,都不会陌生. 操作文本对象的时候,几乎所有的人都会让我们要用 with open ,这就是一个上下文管 ...

  10. 用tornado实现图片标记

    背景介绍   在文章Keras入门(四)之利用CNN模型轻松破解网站验证码中,其中的验证码图片标记是采用tornado实现的网页实现的.本文将会讲述如何利用tornado来实现图片标记.   我们的示 ...