浅谈 PHP Yaf 开启session之后对响应头的影响

时间:2024-09-15 17:03:14

  当使用PHP Yaf框架,如果某个 Action 在返回响应(输出页面或者返回json)之前,启用了session,那么将会在响应头里面加上强制不缓存的响应头,也就是如下的三个响应头。
  
  Expires: Thu, 19 Nov 1981 08:52:00 GMT
  
  Cache-Control: no-store, no-cache, must-revalidate
  
  Pragma: no-cache
  
  测试代码
  
  class IndexController extends Yaf_Controller_Abstract {
  
  // 带有session
  
  public function sessionAction() {
  
  $sessionInstance = \Yaf_Session::getInstance();
  
  $this->getView()->assign("content", "Hello World");
  
  $this->display("index");
  
  return false;
  
  }
  
  // 没有session
  
  public function noSessionAction() {
  
  $this->getView()->assign(www.fengshen157.com"content", "Hello World");
  
  $this->display("index");
  
  return false;
  
  }
  
  }
  
  启用session的请求响应
  
  $ curl -si http://127.0.0.1/index/session
  
  HTTP/1.1 200 OK
  
  Server: openresty/1.11.2.5
  
  Date: Wed, 20 Feb 2019 02:54:47 GMT
  
  Content-Type: text/html; charset=UTF-8
  
  Transfer-Encoding: chunked
  
  Connection: keep-alive
  
  X-Powered-By: PHP/7.0.25
  
  Set-Cookie: PHPSESSID=lf72vsbla12b2431evhp9mq7l6; path=/
  
  Expires: Thu, 19 Nov 1981 08:52:00 GMT
  
  Cache-Control: no-store,www.078881.cn no-cache, must-revalidate
  
  Pragma: no-cache
  
  <html>
  
  <head>
  
  <title>Hello World<www.tianshengyuLe1.cn /title>
  
  </head>
  
  <body>
  
  Hello World </body>
  
  </html>
  
  未启用session的请求响应
  
  $ curl -si http://127.0.0.1/index/nosession
  
  HTTP/1.1 200 OK
  
  Server: openresty/1.11.2.5
  
  Date: Wed, 20 Feb 2019 02:54:40 GMT
  
  Content-Type: text/html;www.yinxionghui1.com charset=UTF-8
  
  Transfer-Encoding: chunked
  
  Connection: keep-alive
  
  X-Powered-By: PHP/7.0.25
  
  <html>
  
  <head>
  
  <title>Hello World</title>
  
  </head>
  
  <body>
  
  Hello World </body>
  
  </html>
  
  整个框架以C API为界,分为前端和后端两大部分。
  
  前端:提供编程模型,多语言的接口支持,比如Python Java C++等。通过C API建立前后端的连接,后面详细讲解。
  
  后端:提供运行环境,完成计算图的执行。进一步分为4层
  
  运行时:分为分布式运行时和本地运行时,负责计算图的接收,构造,编排等。
  
  计算层:提供各op算子的内核实现,例如conv2d, relu等
  
  通信层:实现组件间数据通信,基于GRPC和RDMA两种通信方式
  
  设备层:提供多种异构设备的支持,如CPU GPU TPU FPGA等
  
  模型构造和执行流程
  
  TensorFlow的一大特点是,图的构造和执行相分离。用户添加完算子,构建好整图后,才开始进行训练和执行,也就是图的执行。大体流程如下
  
  图构建:用户在client中基于TensorFlow的多语言编程接口,添加算子,完成计算图的构造。
  
  图传递:client开启session,通过它建立和master之间的连接。执行session.run()时,将构造好的graph序列化为graphDef后,以protobuf的格式传递给master。
  
  图剪枝:master根据session.run()传递的fetches和feeds列表,反向遍历全图full graph,实施剪枝,得到最小依赖子图
  
  图分裂:master将最小子图分裂为多个Graph Partition,并注册到多个worker上。一个worker对应一个Graph Partition。
  
  图二次分裂:worker根据当前可用硬件资源,如CPU GPU,将Graph Partition按照op算子设备约束规范(例如tf.device('/cpu:0'),二次分裂到不同设备上。每个计算设备对应一个Graph Partition。
  
  图运行:对于每一个计算设备,worker依照op在kernel中的实现,完成op的运算。设备间数据通信可以使用send/recv节点,而worker间通信,则使用GRPC或RDMA协议。
  
  3 前端多语言实现 - swig包装器
  
  TensorFlow提供了很多种语言的前端接口,使得用户可以通过多种语言来完成模型的训练和推断。其中Python支持得最好。这也是TensorFlow之所以受欢迎的一大原因。前端多语言是怎么实现的呢?这要归功于swig包装器。
  
  swig是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。在TensorFlow使用bazel编译时,swig会生成两个wrapper文件
  
  pywrap_tensorflow_internal.py:对接上层Python调用
  
  pywrap_tensorflow_internal.cc:对接底层C API调用。
  
  pywrap_tensorflow_internal.py 模块被导入时,会加载_pywrap_tensorflow_internal.so动态链接库,它里面包含了所有运行时接口的符号。而pywrap_tensorflow_internal.cc中,则注册了一个函数符号表,实现Python接口和C接口的映射。运行时,就可以通过映射表,找到Python接口在C层的实现了。
  
  4 tensorflow 源码结构
  
  TensorFlow源码基本也是按照框架分层来组织文件的。如下
  
  其中core为tf的核心,它的源码结构如下
  
  5 总结
  
  TensorFlow框架设计精巧,代码量也很大,我们可以从以下部分逐步学习
  
  TensorFlow内核架构和源码结构。先从全局上对框架进行理解。
  
  前后端连接的桥梁--Session,重点理解session的生命周期,并通过相关源码可以加深理解Python前端如何调用底层C实现。
  
  TensorFlow核心对象—Graph。图graph是TensorFlow最核心的对象,基本都是围绕着它来进行的。graph的节点为算子operation,边为数据tensor。
  
  TensorFlow图的节点 -- Operation。operation是图graph的节点,承载了计算算子。
  
  TensorFlow图的边 -- Tensor。Tensor是图graph的边,承载了计算的数据。
  
  TensorFlow本地运行时。
  
  TensorFlow分布式运行时。和本地运行时有一些共用的接口,但区别也很大。
  
  TensorFlow设备层。主要了解设备层的定义规范,以及实现。
  
  TensorFlow队列和并行运算。
  
  TensorFlow断点检查checkpoint,模型保存Saver,以及可视化tensorboard。这三个为TensorFlow主要的工具。