PHP 使用 xdebug 调试之路

  • PHPStorm中调试利用的是xdebug的remote特性,使用的是 DBGp协议,PHPStorm是一个实现了DBGp协议的客户端
  • php.ini中启用xdebug.remote_enable, 配置xdebug.remote_hostxdebug.remote_port, port默认是9000.
    通过phpinfo()函数的输出,可以在Loaded Configuration File中看到实际加载的php.ini文件是哪一个。
  • sudo apt install php-xdebug之后,会自动在/etc/php/7.0/apache2/conf.d中创建一个xdebug的配置文件,可以在这个文件中修改关于xdebug的配置,而不用去改通用的php.ini.
  • client启动之后会监听 port,等待xdebug发送的请求。
  • 要使php解释器在运行的时候activate xdebug,有三种方式:
    1. 从命令行运行php脚本时,设置环境变量export XDEBUG_CONFIG="idekey=session_name", 同样也可以在XDEBUG_CONFIG环境变量中设置remote_host,remote_port等属性。
    2. 从一个浏览器中启动debugger,需要传递一个XDEBUG_SESSION_START=session_name参数,这个参数可以是GETPOST或者Cookie。可以使用一些浏览器的插件自动传递这个参数。
  • 只要xdebug.remtoe_enable开启了,PHPStorm打开了 Listening for PHP Debug,也就是服务器和客户端都准备好了,然后浏览器发送请求的时候包含一个XDEBUG_SESSION_START参数(?文档中写的是XDEBUG_SESSION_START,而实际上bookmark和插件中设置的cookie都是XDEBUG_SESSION),就可以愉快地调试了。

Python 图片处理库: Pillow

  • Image.open()
    im.mode, im.size, im.format
  • Image.save()
  • Image.show()
    性能很慢, 仅作调试用.
  • Image.convert()
    比较常用的函数
  • Image.crop()
  • Image.paste()
  • Image.split()
    将图像分为不同的 band
  • Image.getpixel()
  • Image.putpixel()
    很慢
  • Image.point()
    可以接受一个 lookup table, 或者一个函数, 函数接受一个参数, 这个参数可以看做像素点的颜色, 返回值为像素点的新颜色
  • Image.thumbnail()
    生成缩略图, 会直接修改原图, 如果要保留原图需要先用 Image.copy()
  • Image.getbbox()
    这个函数好像很好用的样子, 待会儿再尝试
  • Image.getcolors(maxcolors=256)
    获取图片中用到的所有颜色, 返回 [ (count, color),… ]
    如果是 RGB 等格式, color 也是一个 tuple, 所以不同的颜色会有很多, 需要传入较大的 maxcolors, 否则会返回 None
  • Image.histogram()
    获取图片的直方图, 返回一个list, 如果是灰度图像, 则 list 大小为256, 每个元素表示0-255各个灰度的像素点的个数. 如果是 RGB 图像, 则 list 大小为 256*3.

跨域相关

同源策略

origin = 协议 + 域名 + 端口号

同源策略的限制:

  1. Cookie, LocalStorage 和 IndexDB 无法读取
  2. DOM 无法获得
  3. AJAX 无法发送

可跨域的标签 script,img,iframe, link等

JSONP 实质是一种自己发起的XSS

无法在 https 页面发起对非https的请求,会出现 Mixed content 错误

CORS方案

发起跨域请求时,浏览器会自动设置Origin首部,无法手动改变
在服务端的响应中设置Access-Control-Allow-Origin首部
但是这个首部不支持多个 host,所以如果需要支持多个 domain,需要动态地生成这个首部。比如说:

1
2
3
4
5
6
7
< ?php
$allowedOrigins = array("http://example.com", "http://localhost:63342");
$headers = getallheaders();
if ($headers["Origin"] && in_array($headers["Origin"], $allowedOrigins)) {
header("Access-Control-Allow-Origin: " . $headers["Origin"]);
}
?>

是否发送凭证

客户端:

1
2
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

服务端添加 Access-Control-Allow-Credentials : true首部,如果服务器端没有返回这个首部,即使当前domain是允许的,客户端也得不到响应。会有类似 XMLHttpRequest cannot load http://example.com/index.php. Credentials flag is ‘true’, but the ‘Access-Control-Allow-Credentials’ header is ”. It must be ‘true’ to allow credentials. Origin ‘http://localhost:63342‘ is therefore not allowed access. 的提示。

当开启 withCredential 属性时,服务器返回的Access-Control-Allow-Origin不允许为*

Preflight

当跨域请求不是简单请求时,浏览器会先发送一个预检请求(preflight)

浏览器先通过OPTIONS方法询问 request的方法和首部是否支持:

Access-Control-Request-Method

Access-Control-Request-Headers

如果服务端允许跨域请求,则返回几个特殊的首部:

Access-Control-Allow-Methods:必需。返回所有支持的方法,而不单是浏览器请求的那个方法,这是为了避免多次预检请求。

Access-Control-Allow-Headers:如果请求中有Access-Control-Request-Headers,则必需。返回所有支持的首部信息。

Access-Control-Allow-Credentials

Access-Control-Allow-Max-Age:可选,指定本次预检的有效期,单位为秒。

一旦服务器通过了预检,以后每次浏览器正常的CORS请求都跟简单请求一样,包含一个Origin首部,服务器的相应也会有一个Access-Control-Allow-Origin

crossorigin属性

通常 <link> <script> <img>这些本身就可以跨域的标签,在请求时不会发送Origin首部,所以我们也无法使用 JS 获取他们的内容(会报错)。如果为这些标签设置crossorigin属性,则请求时就会使用CORS请求,并且设置了Origin首部。

crossorigin有两个可能的值:anonymouse:不会发送credentials,use-credentials:发送credentials

参考链接

  1. 浏览器同源政策及其规避方法
  2. 跨域资源共享 CORS 详解

TensorFlow 初试

安装

  1. pip install tensorflow

  2. 如果安装GPU版本的,需要安装 Cuda Toolkit 8.0 和 cuDNN v5.1
    pip install tensorflow-gpu
    并且设置环境变量 LD_LIBRARY_PATHCUDA_HOME

  3. 运行 demo model

    python -m tensorflow.models.image.mnist.convolutional

127.0.1.1是什么?

Some software (e.g., GNOME) expects the system hostname to be resolvable to an IP address with a canonical fully qualified domain name. This is really improper because system hostnames and domain names are two very different things; but there you have it. In order to support that software, it is necessary to ensure that the system hostname can be resolved. Most often this is done by putting a line in /etc/hosts containing some IP address and the system hostname. If your system has a permanent IP address then use that; otherwise use the address 127.0.1.1.

/etc/hosts

/etc/hostname

The system hostname should always be resolvable even when the network is down. Basically, some applications still try to resolve a host via 127.0.1.1 so in order to accommodate, it is kept by default on current debian-type distributions.

The general rule of thumb is: If you don’t have a permanent IP address for your host, use 127.0.1.1.