0%

你喜欢的姑娘在学习

查看python的版本

1
2
#python  -V    
Python 2.6.6

下载Python-2.7.3

1
#wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2  

解压

1
#tar -jxvf Python-2.7.3.tar.bz2  

更改工作目录

1
#cd Python-2.7.3  

安装

1
2
3
4
5
#./configure  
#make all
#make install
#make clean
#make distclean

查看版本信息

1
#/usr/local/bin/python2.7 -V  

建立软连接,使系统默认的 python指向 python2.7

1
2
#mv /usr/bin/python /usr/bin/python2.6.6  
#ln -s /usr/local/bin/python2.7 /usr/bin/python

重新检验Python 版本

1
#python -V

解决系统 Python 软链接指向 Python2.7 版本后,因为yum是不兼容 Python 2.7的,所以yum不能正常工作,我们需要指定 yum 的Python版本

1
#vi /usr/bin/yum  

将文件头部的

1
#!/usr/bin/python

改成

1
#!/usr/bin/python2.6

穷人什么苦都能吃就是吃不了学习的苦.
### 客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
// 创建一个Socket实例
var socket =null;//初始是null
var isLogin=false;//是否登录到服务器上

function send()
{
if(!isLogin)
{
alert("请先服务器验证");
return;
}
var msg=document.getElementById("txtmsg").value;
socket.send("msg:"+msg);
//在div 中显示我们的行为
var p=document.createElement("P");
p.innerHTML="<span>发送消息</span>"+msg
document.getElementById("txtcontent").appendChild(p);
}
function connectServer()
{
var userName=document.getElementById("username").value;
if(userName=="")
{
alert("用户昵称必填 ");
return;
}
socket=new WebSocket('ws://121.42.176.99:9091/');
// 打开Socket
socket.onopen = function(event) {
socket.send("login:"+userName);
};
socket.onmessage = function(event) {

var getMsg=event.data;
if(/^notice:success$/.test(getMsg)) //服务器验证通过,后面做任何发送操作
{
isLogin=true;
}
else if(/^msg:/.test(getMsg)) //代表是普通消息
{
//<p>xxxxooo</p>
var p=document.createElement("P");
p.innerHTML="<span>收到消息</span>"+getMsg.replace("msg:","");
document.getElementById("txtcontent").appendChild(p);
}
else if(/^users:/.test(getMsg))
{//显示当前已登录用户
getMsg=getMsg.replace("users:","");
getMsg=eval("("+getMsg+")");
document.getElementById("listusers").innerHTML="";
for(var key in getMsg)
{
var option=document.createElement("OPTION");
option.value=key;//IP
option.innerHTML=getMsg[key];//昵称
document.getElementById("listusers").appendChild(option);
}
}
else
{

}
};
// 监听Socket的关闭
socket.onclose = function(event) {
isLogin=false;

};
}
</script>
</head>
<body>
<div>
<div id="txtcontent" style="width:500px;height:250px;border: solid 1px gray">

</div>
<div>所有用户:<select id="listusers"></select> </div>
<div>你的昵称:<input type="text" id="username"/> </div>
<div>
消息内容:
<textarea style="width:500px;height:100px" id="txtmsg">

</textarea>
</div>
<div>
<button onclick="connectServer()">连接服务器</button>
<button onclick="send()">发送消息</button>
</div>
</div>

</body>
</html>

服务器端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php

//本机ip 121.42.176.99
//等下 要监听 9091端口

require_once __DIR__ . '/Workerman/Autoloader.php';
use Workerman\Worker;
use Workerman\Connection\AsyncTcpConnection;

// 创建一个Worker监听2345端口,使用http协议通讯
$tcp_worker = new Worker("websocket://121.42.176.99:9091");

// 启动1个进程对外提供服务
$tcp_worker->count = 1;
$clients=[];//保存客户端信息

$tcp_worker->onMessage = function($connection, $data)
{
global $clients;
if(preg_match("/^login:(\w{3,20})/i",$data,$result))//代表是客户端认证
{
if(!array_key_exists($connection->getRemoteIp(),$clients)) //必须是之前没有记录过
{
// $clients[$connection->getRemoteIp()]=$result[1];//保存所有客户端 格式为 ip=>昵称
$clients[$connection->getRemoteIp()]=["ip"=>$connection->getRemoteIp(),"name"=>$result[1],"conn"=>$connection];

$connection->send("notice:success");//代表给客户端一个连接提示
$connection->send("msg:welcome back ".$result[1]);//代表是发送普通文字消息
echo $connection->getRemoteIp().":".$result[1]." login".PHP_EOL;


//$connection->send("users:".json_encode($clients));
$users="users:".json_encode(array_column($clients,"name","ip"));
foreach($clients as $ip=>$set)
{
$set["conn"]->send($users);
}

}

}
else if(preg_match("/^msg:(.*?)/isU",$data,$msgset)) //代表 是客户端发送普通消息
{
if(array_key_exists($connection->getRemoteIp(),$clients)) //必须已经认证过得客户端
{
echo "get msg :".$msgset[1];
}
}
$connection->onClose=function ($connection)//客户端主动关闭
{
global $clients;
unset($clients[$connection->getRemoteIp()]);
};
};
$tcp_worker->onClose=function ($connection) use($clients)
{

};


// 运行worker
Worker::runAll();

你不能把这个世界,让给你所鄙视的人。

简单的三行代码就可以实现:

1
2
3
from PIL import ImageGrab
pic = ImageGrab.grab()
pic.save('1.jpg')

使用 selenium

1
2
3
4
5
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://news.baidu.com/')
browser.save_screenshot('capture.png')
browser.close()

加载js,使网页显示完全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from selenium import webdriver
import time

def take_screenshot(url, save_fn="capture.png"):
browser = webdriver.Chrome() # Get local session of firefox
browser.set_window_size(1200, 900)
browser.get(url) # Load page
browser.execute_script("""
(function () {
var y = 0;
var step = 100;
window.scroll(0, 0);

function f() {
if (y < document.body.scrollHeight) {
y += step;
window.scroll(0, y);
setTimeout(f, 100);
} else {
window.scroll(0, 0);
document.title += "scroll-done";
}
}

setTimeout(f, 1000);
})();
""")

for i in xrange(30):
if "scroll-done" in browser.title:
break
time.sleep(10)

browser.save_screenshot(save_fn)
browser.close()

if __name__ == "__main__":

take_screenshot("http://codingpy.com")

使用 PhantomJS(效果不太好)

1
2
3
4
5
from selenium import webdriver
br = webdriver.PhantomJS()
br.get('http://www.baidu.com')
br.save_screenshot('screenshot.png')
br.quit()

升级版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import StringIO
from selenium import webdriver
from PIL import Image

# Install instructions
#
# npm install phantomjs
# sudo apt-get install libjpeg-dev
# pip install selenium pillow


driver = webdriver.PhantomJS()
driver.set_window_size(1366, 728) # optional
driver.get('http://hassyon.com')
driver.save_screenshot('screen_hires.png')

screen = driver.get_screenshot_as_png()

# Crop it back to the window size (it may be taller)
box = (0, 0, 1366, 728)
im = Image.open(StringIO.StringIO(screen))
region = im.crop(box)
region.save('screen_lores.jpg', 'JPEG', optimize=True, quality=95)

这十年来做过的事,能令你无悔骄傲吗? 那时候你所相信的事,应该没动摇吧?
如果要安装的扩展在php源码ext目录中没有,那么这个扩展需要到http://pecl.php.net 搜索下载

以安装libevent扩展为例(假设系统安装了libevent-dev库)

1、下载libevent扩展文件压缩包(在当前系统哪个目录下载随意)

1
2
3
4
5
6
7
8
9
~# wget http://pecl.php.net/get/libevent-0.1.0.tgz
--2015-05-26 21:43:40-- http://pecl.php.net/get/libevent-0.1.0.tgz
Resolving pecl.php.net... 104.236.228.160
Connecting to pecl.php.net|104.236.228.160|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 9806 (9.6K) [application/octet-stream]
Saving to: “libevent-0.1.0.tgz”

100%[=======================================================>] 9,806 41.4K/s in 0.2s

2、解压扩展文件压缩包

1
2
3
4
5
6
~# tar -zxvf libevent-0.1.0.tgz
package.xml
libevent-0.1.0/config.m4
libevent-0.1.0/CREDITS
libevent-0.1.0/libevent.c
....

3、进入到源码目录

1
~# cd libevent-0.1.0/

4、运行phpize命令

1
2
3
4
5
~# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626

5、运行configure命令

1
2
3
4
5
6
7
~# ./configure
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for a sed that does not truncate output... /bin/sed
checking for cc... cc
checking whether the C compiler works... yes
...

6、运行make命令

1
2
~# /bin/bash /data/test/libevent-0.1.0/libtool --mode=compile cc  -I. -I/data/test/libevent-0.1.0 -DPHP_ATOM_INC -I/data/test/libevent-0.1.0/include
...

7、运行make install命令

1
2
~# make install
Installing shared extensions: /usr/lib/php5/20090626/

8、配置ini文件

1
通过运行 php --ini查找php.ini文件位置,然后在文件中添加extension=libevent.so

http://doc3.workerman.net/appendices/install-extension.html

总有一天,我会拥有我梦寐以求的6块腹肌,可是我还是先把这个汉堡吃完……

什么是PEAR

PEAR的全称是PHP Extension and Application Repository,是PHP的扩展库,采用PHP语言编写。所以我们可以直接下载,并在我们的代码中包含(include)扩展库。

什么是PECL

PECL的全称是PHP Extension Community Library,它也是PHP的扩展库。PECL的扩展都是采用C语言编写的,可以被载入PHP中,给PHP增加额外的功能,比如PHP的Mongo扩展。
即 php 的 so 格式的扩展

centos

  • 安装: yum install php-pear

ubuntu

  • 安装: sudo apt-get install php-pear

phpize

centos

  • 安装: yum install php-devel
  • 查看: which phpize

其他

在网页中打印phpinfo()看到安装了某个扩展,不代表命令行的PHP CLI也安装了对应的扩展。

  • 如何确定PHP CLI安装了哪些扩展

运行 php -m 会列出命令行 PHP CLI 已经安装的扩展

  • 如何确定PHP CLI 的php.ini文件的位置

可以运行php --ini查找PHP CLI的ini文件位置

我喜欢你,像风走了八万里,不问归期。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
git checkout . #本地所有修改的。没有的提交的,都返回到原来的状态
git stash #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。
git reset --hard HASH #返回到某个节点,不保留修改。
git reset --soft HASH #返回到某个节点。保留修改

git clean -df #返回到某个节点
git clean 参数
-n 显示 将要 删除的 文件 和 目录
-f 删除 文件
-df 删除 文件 和 目录
也可以使用:

git checkout . && git clean -xdf

我是主角,我不能死。
mysql在创建表的时候定义表的性质(也叫表的类型),共有三种:静态表,动态表,压缩表。默认是静态表,如果存在varchar、blob、text字段,表类型就是动态了。

静态表

字段有固定长度,例如:char(20)。如果使用gbk字符集存储中文username,将占用40byte,如果username的实际内容没有达到 40byte,将会填充空格,以达到40byte。速度很快,因为mysql知道username总是从第41个字节开始,容易缓存,出现问题后也容易恢 复(mysql知道记录的确切位置),需要更多的硬盘空间(如果有三个上面的字段,一条记录就会占120字节,即使实际只用了其中一部分)

动态表

字 段不定长(变长),这种表格式比较节省空间,但是复杂度更高,每条记录都有一个header,作用就是表明该记录有多长,所有的字符串列都是动态的(除非 小于4个字节,这种情况下,节省的空间可以忽略不计,增加的复杂度会反而会导致性能丢失),通常占用比静态表少的多地空间,但是必须经常维护(避免碎 片),例如:更新了用户名somebody为somebodyt,t不能立刻就出现在y的后面,因为空间被其他记录占用,对于出现碎片的列,每个新连接会 损失6个字节。而且出现问题后不容易重建(前面我说的静态表正好相反),如果碎片严重,有可能出现库爆炸(^_^).

不包括连接的动态记录的空间消耗可以用下面的公式计算:
3+(列数+7)/8+(字符列数)+数字列的打包尺寸+字符串长度+(空列的数量+7)/8

每条记录的header可以表明那个字符串列是空的,那个数字列包含0(非空),在那种情况下不向磁盘存储,非空字符串包含一个长度字节加上字符串内容。

压缩表

只读,使用很少的空间,用myisampack工具创建,表要少得多,每条记录分开压缩,所以不能同时访问,可以压缩静态表和动态表。
创建方法:myisampack [options] filename

你不能把这个世界,让给你所鄙视的人。
### 安装步骤 - 下载https://github.com/ErikDubbelboer/phpRedisAdmin - 解压到您的web目录下 - 在该目录下运行命令composer install

推荐软件

  • keylord-windows(收费)

redis服务(windows)

水来我在漩涡中等你 火来我在灰烬中等你
默认情况下,Redis 服务会提供 16 个数据库,Laravel 使用数据库 0 作为缓存和 Session 的存储。 在使用的过程中觉得这个默认的设置挺不合理,因为当你在执行命令`php artisan cache:clear` 的时候,会把 Session 也连带清除了,导致所有用户需要重新登录。

配置 Session Redis 数据库

修改 config/database.php,在 redis 选项内增加 session 选项,并把 database 修改为 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'redis' => [

'cluster' => false,

'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],

'session' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 1,
],
],

指定 Session 使用数据库

修改 config/session.php

1
'connection' => 'session',

开始使用

修改 .env 文件的 SESSION_DRIVER 选项为 redis,开始应用上。

1
SESSION_DRIVER=redis

全体听令,除我之外~冲锋!

配置文件database.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'redis' => [

'cluster' => false,

'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],

'product' => [
'host' => 'localhost',
'password' => null,
'port' => 6379,
'database' => 1,
]
],

连接存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 连接
public static function connectDatabase($name)
{
return Redis::connection($name);
}

// 存储
$redisConnection = parent::getRedisConnectName();
$redis = RedisHelper::connectDatabase($redisConnection['store']);
$redis->rpush('productView', $product_id);

// 取出
$products = array_count_values($redis->lrange('productView',0,-1));

// 删除
$redis->del('productView');