Gowhich

Durban's Blog

安装:

现在地址:http://www.nodejs.org/download/

可以根据自己的系统类型,选择对应的安装文件,进行安装

测试

写一个简单的hello world

1
2
3
4
5
6
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');

使用浏览器,输入url地址http://127.0.0.1:8124/,可以看到输出Hello World字符串,如果没有说明出现问题了。

元素透明的做法,大概如下

1
#div.opacity{ filter:alpha(opacity:80);opacity:0.8; }

但是结果导致的问题是,里面所有的元素都开始透明了

通过搜索,搜集资料,我发现了一个解决问题的方法

HTML文件代码如下:

1
2
3
4
5
6
7
8
9
10
11
<div class='well activity-outer'>
<div class='activity-opacity'></div>
<div class='activity-inner'>
<h4>活动细则:</h4>
<div class='detail'>
<p style='margin:0;padding:0;text-indent:1em'>1. 手机拍摄黑龙江卫视乱世佳人照片并上传, 选择上传到“天心恋”和“重心恋”其中一组</p>
<p style='margin:0;padding:0;text-indent:1em'>2. 普通观众点击支持,看哪些照片(带黑龙江卫视台标)获得支持多,优先获得奖品</p>
<p style='margin:0;padding:0;text-indent:1em'>3. 本活动在和黑龙江卫视播出最后一期结束</p>
</div>
</div>
</div>

CSS文件代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
div.activity-outer{padding:0;background-color:transparent;border:0}
div.activity-opacity,
div.activity-inner{
height:100px;
width:938px;
left:0;
position:relative;
top:0;
border-radius: 4px 4px 4px 4px;
border-color:#ccc;
}

div.activity-opacity{
background-color:#ccc;
filter:alpha(opacity:80);
opacity:.8;
}
div.activity-inner{
margin-top: -119px;
padding: 14px 4px 0 10px;
color:white
}

以上两个文件的代码,是我做的网站的一个摘录,主css文件采用的是bootstrap这个css框架,记录一下。

在使用关联AR之前,首先要在数据库中建立关联的数据表之间的主键-外键关联,AR需要通过分析数据库中的定义数据表关联的元信息,来决定如何连接数据。

如何声明关联

在使用AR进行关联查询之前,我们需要告诉AR各个AR类之间有怎样的关联。
AR类之间的关联直接反映着数据库中这个类所代表的数据表之间的关联。从关系数据库的角度来说,两个数据表A,B之间可能的关联有三种:一对多,一对一,多对多。而在AR中,关联有以下四种:
BELONGS_TO: 如果数据表A和B的关系是一对多,那我们就说B属于A(B belongs to A)。
HAS_MANY: 如果数据表A和B的关系是多对一,那我们就说B有多个A(B has many A)。
HAS_ONE: 这是‘HAS_MANY’关系中的一个特例,当A最多有一个的时候,我们说B有一个A (B has one A)。
MANY_MANY: 这个相当于关系数据库中的多对多关系。因为绝大多数关系数据库并不直接支持多对多的关系,这时通常都需要一个单独的关联表,把多对多的关系分解为两个一对
多的关系。用AR的方式去理解的话,我们可以认为 MANY_MANY关系是由BELONGS_TO和HAS_MANY组成的。
在AR中声明关联,是通过覆盖(Override)父类CActiveRecord中的relations()方法来实现的。这个方法返回一个包含了关系定义的数组,数组中的每一组键值代表一个关联:
'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)
这里的VarName是这个关联的名称;
RelationType指定了这个关联的类型,有四个常量代表了四种关联的类型:self::BELONGS_TOself::HAS_ONEself::HAS_MANYself::MANY_MANY
ClassName是这个关系关联到的AR类的类名;
ForeignKey指定了这个关联是通过哪个外键联系起来的。后面的additional
options可以加入一些额外的设置,后面会做介绍。

下面的代码演示了如何定义User和Post之间的关联。

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
<?php
class Post extends CActiveRecord
{
public function relations()
{
return [
'author' => [
self::BELONGS_TO,
'User',
'authorID',
],
'categories' => [
self::MANY_MANY,
'Category',
'PostCategory(postID, categoryID)',
],
];
}
}

class User extends CActiveRecord
{
public function relations()
{
return [
'posts' => [
self::HAS_MANY,
'Post',
'authorID',
],
'profile' => [
self::HAS_ONE,
'Profile',
'ownerID',
],
];
}
}

说明: 有时外键可能由两个或更多字段组成,在这里可以将多个字段名由逗号或空格分隔,一并写在这里。对于多对多的关系,关联表必须在外键中注明,例如在Post类的categories关联中,外键就需要写成PostCategory(postID, categoryID)。
在AR类中声明关联时,每个关联会作为一个属性添加到AR类中,属性名就是关联的名称。在进行关联查询时,这些属性就会被设置为关联到的AR类的实例,例如在查询取得一个Post实例时,它的$author属性就是代表Post作者的一个User类的实例。

关联查询

进行关联查询最简单的方式就是访问一个关联AR对象的某个关联属性。如果这个属性之前没有被访问过,这时就会启动一个关联查询,
通过当前AR对象的主键连接相关的表,来取得关联对象的值,然后将这些数据保存在对象的属性中。这种方式叫做“延迟加载”,也就是只有等到访问到某个属性时,
才会真正到数据库中把这些关联的数据取出来。下面的例子描述了延迟加载的过程:

1
2
3
4
// retrieve the post whose ID is 10
$post=Post::model()->findByPk(10);
// retrieve the post's author: a relational query will be performed here
$author=$post->author;

在不同的关联情况下,如果没有查询到结果,其返回的值也不同:BELONGS_TO 和 HAS_ONE 关联,无结果时返回null; HAS_MANY 和 MANY_MANY, 无结果时返回空数组。
延迟加载方法使用非常方便,但在某些情况下并不高效。例如,若我们要取得N个post的作者信息,使用延迟方法将执行N次连接查询。此时我们应当使用所谓的急切加载方法。
急切加载方法检索主要的 AR 实例及其相关的 AR 实例. 这通过使用 with() 方法加上 find 或 findAll 方法完成。例如,
$posts=Post::model()->with('author')->findAll();
上面的代码将返回一个由 Post 实例组成的数组. 不同于延迟加载方法,每个Post 实例中的author 属性在我们访问此属性之前已经被关联的User 实例填充。
不是为每个post 执行一个连接查询, 急切加载方法在一个单独的连接查询中取出所有的 post 以及它们的author!
我们可以在with()方法中指定多个关联名字。例如, 下面的代码将取回 posts 以及它们的作者和分类:

$posts=Post::model()->with('author','categories')->findAll();
我们也可以使用嵌套的急切加载。不使用一个关联名字列表, 我们将关联名字以分层的方式传递到 with() 方法, 如下,

1
2
3
4
5
$posts = Post::model()->with(
'author.profile',
'author.posts',
'categories'
)->findAll();

上面的代码将取回所有的 posts 以及它们的作者和分类。它也将取出每个作者的profile和 posts.
急切加载也可以通过指定 CDbCriteria::with 属性被执行, 如下:

1
2
3
4
5
6
7
$criteria = new CDbCriteria;
$criteria->with = [
'author.profile',
'author.posts',
'categories',
];
$posts = Post::model()->findAll($criteria);

1
$posts = Post::model()->findAll(['with' => ['author.profile', 'author.posts', 'categories']];

关联查询选项

之前我们提到额外的参数可以被指定在关联声明中。这些选项,指定为 name-value 对,被用来定制关联查询。它们被概述如下:

select: 为关联 AR 类查询的字段列表。默认是 ‘*’, 意味着所有字段。查询的字段名字可用别名表达式来消除歧义(例如:COUNT(??.name) AS nameCount)。
condition: WHERE 子语句。默认为空。注意, 列要使用别名引用(例如:??.id=10)。
params: 被绑定到 SQL 语句的参数. 应当为一个由 name-value 对组成的数组()。
on: ON 子语句. 这里指定的条件将使用 and 操作符被追加到连接条件中。此选项中的字段名应被消除歧义。此选项不适用于 MANY_MANY 关联。
order: ORDER BY 子语句。默认为空。注意, 列要使用别名引用(例如:??.age DESC)。
with: 应当和此对象一同载入的子关联对象列表. 注意, 不恰当的使用可能会形成一个无穷的关联循环。
joinType: 此关联的连接类型。默认是 LEFT OUTER JOIN。
aliasToken:列前缀占位符。默认是“??.”。
alias: 关联的数据表的别名。默认是 null, 意味着表的别名和关联的名字相同。
together: 是否关联的数据表被强制与主表和其他表连接。此选项只对于HAS_MANY 和 MANY_MANY 关联有意义。若此选项被设置为 false, ……(此处原文出错!).默认为空。此选项中的字段名以被消除歧义。
having: HAVING 子语句。默认是空。注意, 列要使用别名引用。
index: 返回的数组索引类型。确定返回的数组是关键字索引数组还是数字索引数组。不设置此选项, 将使用数字索引数组。此选项只对于HAS_MANY 和 MANY_MANY 有意义

此外, 下面的选项在延迟加载中对特定关联是可用的:

group: GROUP BY子句。默认为空。注意, 列要使用别名引用(例如:??.age)。 本选项仅应用于HAS_MANY 和 MANY_MANY 关联。
having: HAVING子句。默认为空。注意, 列要使用别名引用(例如:??.age)。本选项仅应用于HAS_MANY 和 MANY_MANY 关联。
limit: 限制查询的行数。本选项不能用于BELONGS_TO关联。
offset: 偏移。本选项不能用于BELONGS_TO关联。

下面我们改变在 User 中的 posts 关联声明,通过使用上面的一些选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class User extends CActiveRecord
{
public function relations()
{
return [
'posts' => [self::HAS_MANY, 'Post', 'author_id',
'order' => 'posts.create_time DESC',
'with' => 'categories',
],
'profile' => [self::HAS_ONE, 'Profile', 'owner_id'],
];
}
}

现在若我们访问 $author->posts, 我们将得到用户的根据发表时间降序排列的 posts. 每个 post 实例也载入了它的分类。

为字段名消除歧义

当一个字段的名字出现在被连接在一起的两个或更多表中,需要消除歧义(disambiguated)。可以通过使用表的别名作为字段名的前缀实现。
在关联AR查询中,主表的别名确定为 t,而一个关联表的别名和相应的关联的名字相同(默认情况下)。 例如,在下面的语句中,Post 的别名是 t ,而 Comment 的别名是 comments:
$posts=Post::model()->with('comments')->findAll();
现在假设 Post 和 Comment 都有一个字段 create_time , 我们希望取出 posts 及它们的 comments,
排序方式是先根据 posts 的创建时间,然后根据 comment 的创建时间。
我们需要消除create_time 字段的歧义,如下:

1
2
3
4
5
$posts = Post::model()
->with('comments')
->findAll([
'order' => 't.create_time, comments.create_time';,
]);

默认情况下,Yii 自动为每个关联表产生一个表别名,我们必须使用此前缀 ??. 来指向这个自动产生的别名。 主表的别名是表自身的名字。

动态关联查询选项

我们使用 with()和 with 均可使用动态关联查询选项。 动态选项将覆盖在 relations() 方法中指定的已存在的选项。
例如,使用上面的 User 模型, 若我们想要使用急切加载方法以升序来取出属于一个作者的 posts(关联中的order 选项指定为降序), 我们可以这样做:

1
2
3
4
5
6
7
8
User::model()->with(
[
'posts' => [
'order' => 'posts.create_time ASC',
],
'profile',
]
)->findAll();

动态查询选项也可以在使用延迟加载方法时使用以执行关联查询。 要这样做,我们应当调用一个方法,它的名字和关联的名字相同,并传递动态查询选项 作为此方法的参数。例如,下面的代码返回一个用户的 status 为 1 的 posts :

1
2
$user = User::model()->findByPk(1);
$posts = $user->posts(['condition' => 'status=1']);

关联查询的性能

如上所述,急切加载方法主要用于当我们需要访问许多关联对象时。 通过连接所有所需的表它产生一个大而复杂的 SQL 语句。
一个大的 SQL 语句在许多情况下是首选的。然而在一些情况下它并不高效。考虑一个例子,若我们需要找出最新的文章以及它们的评论。
假设每个文章有 10 条评论,使用一个大的 SQL 语句,我们将取回很多多余的 post
数据, 因为每个post 将被它的每条评论反复使用。现在让我们尝试另外的方法:我们首先查询最新的文章,
然后查询它们的评论。用新的方法,我们需要执行执行两条 SQL 语句。有点是在查询结果中没有多余的数据。
因此哪种方法更加高效?没有绝对的
答案。执行一条大的 SQL 语句也许更加高效,因为它需要更少的花销来解析和执行 SQL 语句。另一方面,使用单条 SQL语句,我们得到更多冗余的数据,因此需要更多时间来阅读和处理它们。
因为这个原因,Yii 提供了 together 查询选项以便我们在需要时选择两种方法之一。
默认下, Yii 使用第一种方式,即产生一个单独的 SQL语句来执行急切加载。我们可以在关联声明中设置 together 选项为 false 以便一些表被连接在单独的 SQL语句中。
例如,为了使用第二种方法来查询最新的文章及它们的评论,我们可以在 Post 类中声明 comments 关联如下,

1
2
3
4
5
6
function relations()
{
return [
'comments' => [self::HAS_MANY, 'Comment', 'post_id', 'together' => false],
];
}

当我们执行急切加载时,我们也可以动态地设置此选项:

1
$posts = Post::model()->with(['comments' => ['together' => false]])->findAll();

统计查询

除了上面描述的关联查询,Yii 也支持所谓的统计查询(或聚合查询)。 它指的是检索关联对象的聚合信息,例如每个 post的评论的数量,每个产品的平均等级等。
统计查询只被 HAS_MANY(例如,一个 post 有很多评论) 或 MANY_MANY (例如,一个 post 属于很多分类和一个 category 有很多 post) 关联对象执行。
执行统计查询非常类似于之前描述的关联查询。我们首先需要在 CActiveRecord 的 relations() 方法中声明统计查询。

1
2
3
4
5
6
7
8
9
10
class Post extends CActiveRecord
{
public function relations()
{
return [
'commentCount' => [self::STAT, 'Comment', 'post_id'],
'categoryCount' => [self::STAT, 'Category', 'post_category(post_id,category_id)'],
];
}
}

在上面,我们声明了两个统计查询:commentCount 计算属于一个 post 的评论的数量,categoryCount 计算一个 post所属分类的数量。
注意 Post 和 Comment 之间的关联类型是 HAS_MANY, 而 Post 和 Category 之间的关联类型是 MANY_MANY (使用连接表 PostCategory)。
如我们所看到的,声明非常类似于之间小节中的关联。唯一的不同是这里的关联类型是STAT。
有了上面的声明,我们可以检索使用表达式 $post->commentCount 检索一个 post 的评论的数量。
当我们首次访问此属性,一个 SQL 语句将被隐含地执行并检索 对应的结果。我们已经知道,这是所谓的 lazy loading方法。若我们需要得到多个post 的评论数目,我们也可以使用 eager loading 方法:
$posts=Post::model()->with('commentCount', 'categoryCount')->findAll();
上面的语句将执行三个 SQL 语句以取回所有的 post 及它们的评论数目和分类数目。使用延迟加载方法, 若有 N 个 post ,我们使用 2N+1 条 SQL 查询完成。
默认情况下,一个统计查询将计算 COUNT 表达式(and thus the comment count and category countin the above example).
当我们在 relations()中声明它时,通过 指定额外的选项,可以定制它。可用的选项简介如下。
select: 统计表达式。默认是 COUNT(
),意味着子对象的个数。
defaultValue: 没有接收一个统计查询结果时被赋予的值。例如,若一个 post 没有任何评论,它的 commentCount 将接收此值。此选项的默认值是 0。
condition: WHERE 子语句。默认是空。
params: 被绑定到产生的SQL 语句中的参数。它应当是一个 name-value 对组成的数组。
order: ORDER BY 子语句。默认是空。
group: GROUP BY 子语句。默认是空。
having: HAVING 子语句。默认是空。

关联查询命名空间

关联查询也可以和 命名空间一起执行。有两种形式。第一种形式,命名空间被应用到主模型。第二种形式,命名空间被应用到关联模型。
下面的代码展示了如何应用命名空间到主模型。
$posts=Post::model()->published()->recently()->with('comments')->findAll();
这非常类似于非关联的查询。唯一的不同是我们在命名空间后使用了 with() 调用。 此查询应当返回最近发布的 post和它们的评论。
下面的代码展示了如何应用命名空间到关联模型。
$posts=Post::model()->with('comments:recently:approved')->findAll();
上面的查询将返回所有的 post 及它们审核后的评论。注意 comments 指的是关联名字,而 recently 和 approved 指的是 在 Comment 模型类中声明的命名空间。关联名字和命名空间应当由冒号分隔。
命名空间也可以在 CActiveRecord::relations() 中声明的关联规则的 with 选项中指定。在下面的例子中, 若我们访问 $user->posts,它将返回此post 的所有审核后的评论。

1
2
3
4
5
6
7
8
9
class User extends CActiveRecord
{
public function relations()
{
return [
'posts' => [self::HAS_MANY, 'Post', 'author_id', 'with' => 'comments:approved'],
];
}
}

注意: 应用到关联模型的命名空间必须在 CActiveRecord::scopes 中指定。结果,它们不能被参数化。

获取远程文件大小及信息的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
function getFileSize($url)
{
$url = parse_url($url);
if ($fp = @fsockopen($url[’host’], empty($url[’port’]) ? 80 : $url[’port’], $error)) {
fputs($fp, "GET " . (empty($url[’path’]) ? ’ / ’ : $url[’path’]) . " HTTP/1.1\r\n");
fputs($fp, "Host:$url[host]\r\n\r\n");
while (!feof($fp)) {
$tmp = fgets($fp);
if (trim($tmp) == ’’) {
break;
} else if (preg_match(’ / Content - Length:( . * ) / si’, $tmp, $arr)) {
return trim($arr[1]);
}
}
return null;
} else {
return null;
}
}

echo getFileSize("http://www.dianpub.com/download/xml.rar");

图片

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
<?php
//记录程序开始的时间
$BeginTime = getmicrotime();

function GrabImage($url, $filename = "")
{
if ("" == $url): return false;
if ("" == $filename) {
$ext = strrchr($url, ".");
if (".gif" != $ext && ".jpg" != $ext): return false;
$filename = date("dMYHis") . $ext;
}
ob_start();
readfile($url);
$img = ob_get_contents();
ob_end_clean();
$size = strlen($img);
$fp2 = @fopen($filename, "a");
fwrite($fp2, $img);
fclose($fp2);
return $filename;
}

$img = GrabImage("http://www.dianpub.com/images/_1978837_detector_ap100.jpg", "");
if ($img): echo '<pre><img src="' . $img . '"></pre>';else:echo "false";

//记录程序运行结束的时间
$EndTime = getmicrotime();

//返回运行时间
exit($EndTime - $BeginTime);

全文下载图片

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
<?php
if (!empty($saveremoteimg)) {
$body = stripslashes($body);
$img_array = [];
preg_match_all("/(src|SRC)=[\"|'| ]{0,}(http:\/\/(.*)\.(gif|jpg|jpeg|bmp|png))/isU", $body, $img_array);
$img_array = array_unique($img_array[2]);
set_time_limit(0);
$imgUrl = $img_dir . "/" . strftime("%Y%m%d", time());
$imgPath = $base_dir . $imgUrl;
$milliSecond = strftime("%H%M%S", time());
if (!is_dir($imgPath)) {
@mkdir($imgPath, 0777);
}

foreach ($img_array as $key => $value) {
$value = trim($value);
$get_file = @file_get_contents($value);
$rndFileName = $imgPath . "/" . $milliSecond . $key . "." . substr($value, -3, 3);
$fileurl = $imgUrl . "/" . $milliSecond . $key . "." . substr($value, -3, 3);
if ($get_file) {
$fp = @fopen($rndFileName, "w");
@fwrite($fp, $get_file);
@fclose($fp);
}
$body = ereg_replace($value, $fileurl, $body);
}
$body = addslashes($body);
}

PHP远程文件下载类(支持断点续传)

1)功能:支持断点续传的下载,能计算传输率,能控制传输率

简易使用方法:

1
2
3
4
5
<?php
$object = new httpdownload();
$object->set_byfile($file);//服务器文件名,包括路径
$object->filename = $filename;//下载另存为的文件名
$object->download();

类文件:

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
<?php
class httpdownload
{
public $data = null;
public $data_len = 0;
public $data_mod = 0;
public $data_type = 0;
public $data_section = 0; //section download
public $sentSize = 0;
public $handler = ['auth' => null];
public $use_resume = true;
public $use_autoexit = false;
public $use_auth = false;
public $filename = null;
public $mime = null;
public $bufsize = 2048;
public $seek_start = 0;
public $seek_end = -1;
public $totalsizeref = 0;
public $bandwidth = 0;
public $speed = 0;
public function initialize()
{
global $HTTP_SERVER_VARS;
if ($this->use_auth) {
if (!$this->_auth()) {
header('WWW-Authenticate: Basic realm="Please enter your username and password"');
header('HTTP/1.0 401 Unauthorized');
header('status: 401 Unauthorized');
if ($this->use_autoexit) {
exit();
}

return false;
}
}
if (null == $this->mime) {
$this->mime = "application/octet-stream";
}
//default mime
if (isset($_SERVER['HTTP_RANGE']) || isset($HTTP_SERVER_VARS['HTTP_RANGE'])) {
if (isset($HTTP_SERVER_VARS['HTTP_RANGE'])) {
$seek_range = substr($HTTP_SERVER_VARS['HTTP_RANGE'], strlen('bytes='));
} else {
$seek_range = substr($_SERVER['HTTP_RANGE'], strlen('bytes='));
}

$range = explode('-', $seek_range);
if ($range[0] > 0) {
$this->seek_start = intval($range[0]);
}
if ($range[1] > 0) {
$this->seek_end = intval($range[1]);
} else {
$this->seek_end = -1;
}

if (!$this->use_resume) {
$this->seek_start = 0;
//header("HTTP/1.0 404 Bad Request");
//header("Status: 400 Bad Request");
//exit;
//return false;
} else {
$this->data_section = 1;
}
} else {
$this->seek_start = 0;
$this->seek_end = -1;
}
$this->sentSize = 0;
return true;
}

public function header($size, $seek_start = null, $seek_end = null)
{
header('Content-type: ' . $this->mime);
header('Content-Disposition: attachment; filename="' . $this->filename . '"');
header('Last-Modified: ' . date('D, d M Y H:i:s \G\M\T', $this->data_mod));
if ($this->data_section && $this->use_resume) {
header("HTTP/1.0 206 Partial Content");
header("Status: 206 Partial Content");
header('Accept-Ranges: bytes');
header("Content-Range: bytes $seek_start-$seek_end/$size");
header("Content-Length: " . ($seek_end - $seek_start + 1));
} else {
header("Content-Length: $size");
}
}

public function download_ex($size)
{
if (!$this->initialize()) {
return false;
}

ignore_user_abort(true);
//Use seek end here
if ($this->seek_start > ($size - 1)) {
$this->seek_start = 0;
}

if ($this->seek_end <= 0) {
$this->seek_end = $size - 1;
}

$this->header($size, $seek, $this->seek_end);
$this->data_mod = time();
return true;
}

public function download()
{
if (!$this->initialize()) {
return false;
}

try {
error_log("begin download\n", 3, "/usr/local/www/apache22/LOGS/apache22_php.err");
$seek = $this->seek_start;
$speed = $this->speed;
$bufsize = $this->bufsize;
$packet = 1;
//do some clean up
@ob_end_clean();
$old_status = ignore_user_abort(true);
@set_time_limit(0);
$this->bandwidth = 0;
$size = $this->data_len;
if (0 == $this->data_type) //download from a file {
{
$size = filesize($this->data);
}

if ($seek > ($size - 1)) {
$seek = 0;
}

if (null == $this->filename) {
$this->filename = basename($this->data);
}

$res = fopen($this->data, 'rb');
if ($seek) {
fseek($res, $seek);
}

if ($this->seek_end < $seek) {
$this->seek_end = $size - 1;
}

$this->header($size, $seek, $this->seek_end); //always use the last seek
$size = $this->seek_end - $seek + 1;
while (!(connection_aborted() || connection_status() == 1) && $size > 0) {
if ($size < $bufsize) {
echo fread($res, $size);
$this->bandwidth += $size;
$this->sentSize += $size;
} else {
echo fread($res, $bufsize);
$this->bandwidth += $bufsize;
$this->sentSize += $bufsize;
}
$size -= $bufsize;
flush();
if ($speed > 0 && ($this->bandwidth > $speed * $packet * 1024)) {
sleep(1);
$packet++;
}
}
fclose($res);

if (1 == $this->data_type) //download from a string
{
if ($seek > ($size - 1)) {
$seek = 0;
}

if ($this->seek_end < $seek) {
$this->seek_end = $this->data_len - 1;
}

$this->data = substr($this->data, $seek, $this->seek_end - $seek + 1);
if (null == $this->filename) {
$this->filename = time();
}

$size = strlen($this->data);
$this->header($this->data_len, $seek, $this->seek_end);
while (!connection_aborted() && $size > 0) {
if ($size < $bufsize) {
$this->bandwidth += $size;
$this->sentSize += $size;
} else {
$this->bandwidth += $bufsize;
$this->sentSize += $bufsize;
}
echo substr($this->data, 0, $bufsize);
$this->data = substr($this->data, $bufsize);
$size -= $bufsize;
flush();
if ($speed > 0 && ($this->bandwidth > $speed * $packet * 1024)) {
sleep(1);
$packet++;
}
}
} else if (2 == $this->data_type) {
//just send a redirect header
header('location: ' . $this->data);
}
if ($this->totalsizeref == $this->sentSize) {
error_log("end download\n", 3, "/usr/local/www/apache22/LOGS/apache22_php.err");
} else {
error_log("download is canceled\n", 3, "/usr/local/www/apache22/LOGS/apache22_php.err");
}

if ($this->use_autoexit) {
exit();
}

//restore old status
ignore_user_abort($old_status);
set_time_limit(ini_get("max_execution_time"));
} catch (Exception $e) {
error_log("cancel download\n" . $e, 3, "/usr/local/www/apache22/LOGS/apache22_php.err");
}
return true;
}

public function set_byfile($dir)
{
if (is_readable($dir) && is_file($dir)) {
$this->data_len = 0;
$this->data = $dir;
$this->data_type = 0;
$this->data_mod = filemtime($dir);
$this->totalsizeref = filesize($dir);
return true;
} else {
return false;
}
}

public function set_bydata($data)
{
if ('' == $data) {
return false;
}

$this->data = $data;
$this->data_len = strlen($data);
$this->data_type = 1;
$this->data_mod = time();
return true;
}

public function set_byurl($data)
{
$this->data = $data;
$this->data_len = 0;
$this->data_type = 2;
return true;
}

public function set_lastmodtime($time)
{
$time = intval($time);
if ($time <= 0) {
$time = time();
}

$this->data_mod = $time;
}

public function _auth()
{
if (!isset($_SERVER['PHP_AUTH_USER'])) {
return false;
}

if (isset($this->handler['auth']) && function_exists($this->handler['auth'])) {
return $this->handler['auth']('auth', $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
} else {
return true;
}
//you must use a handler
}
}

PHP使用GD库下载远程图片

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$imgname = "http://imgdujia.kuxun.cn/newpic/929/812929/4.jpg";
$src_im = imagecreatefromjpeg($imgname);
$srcW = ImageSX($src_im); //获得图像的宽
$srcH = ImageSY($src_im); //获得图像的高

$dst_im = ImageCreateTrueColor($srcW, $srcH); //创建新的图像对象

imagecopy($dst_im, $src_im, 0, 0, 0, 0, $srcW, $srcH);
imagejpeg($dst_im, "newpic.jpg"); //创建缩略图文件

echo "<img src="newpic . jpg" mce_src="newpic . jpg"></img>";
1
2
3
4
5
6
7
8
9
<?php
header("Content-type: image/png");
$im = imagecreatefromjpeg("http://postimg.mop.com/200602/02/74/122374/200602022335325121.JPG");
$white = imagecolorallocate($im, 0xF9, 0xD7, 0xCD);
imagefill($im, 0, 0, $white);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, "A Simple Text String", $text_color);
imagepng($im);
imagedestroy($im);

gzip是GNU zip的缩写,它是一个GNU自由软件的文件压缩程序,可以极大的加速网站.有时压缩比率高到80%,近来测试了一下,最少都有40%以上,还是相当不错的。大道至简,知易行难,悟者大成。

gzip

决定是否开启gzip模块
example:gzip on;

gzip_buffers

设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间
param2:int(k) 后面单位是k
example: gzip_buffers 4 8k;

gzip_comp_level

设置gzip压缩等级,等级越底压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大
param:1-9
example:gzip_com_level 1;

gzip_min_length

当返回内容大于此值时才会使用gzip进行压缩,以K为单位,当值为0时,所有页面都进行压缩
param:int
example:gzip_min_length 1000;

gzip_http_version

用于识别http协议的版本,早期的浏览器不支持gzip压缩,用户会看到乱码,所以为了支持前期版本加了此选项,目前此项基本可以忽略
param: 1.0|1.1
example:gzip_http_version 1.0

gzip_proxied

Nginx做为反向代理的时候启用,
param:off|expired|no-cache|no-sotre|private|no_last_modified|no_etag|auth|any]
expample:gzip_proxied no-cache;
off – 关闭所有的代理结果数据压缩
expired – 启用压缩,如果header中包含”Expires”头信息
no-cache – 启用压缩,如果header中包含”Cache-Control:no-cache”头信息
no-store – 启用压缩,如果header中包含”Cache-Control:no-store”头信息
private – 启用压缩,如果header中包含”Cache-Control:private”头信息
no_last_modified – 启用压缩,如果header中包含”Last_Modified”头信息
no_etag – 启用压缩,如果header中包含“ETag”头信息
auth – 启用压缩,如果header中包含“Authorization”头信息
any – 无条件压缩所有结果数据

gzip_types

设置需要压缩的MIME类型,非设置值不进行压缩
param:text/html|application/x-javascript|text/css|application/xml
example:gzip_types text/html;

Demo

1
2
3
4
gzip on;
gzip_min_length 1000;
gzip_buffers 4 8k;
gzip_types text/html application/x-javascript text/css application/xml;

收集的一些实用的ios代码段

去除顶部状态栏后的分辨率

1
CGRect frame = [[UIScreen mainScreen] applicationFrame];

获取当前SIM卡的手机号码(私有API)

首先引入官方的CoreTelephony库,然后使用如下函数返回用户手机号码即可:

1
2
extern NSString *CTSettingCopyMyPhoneNumber();
NSString *telNum = CTSettingCopyMyPhoneNumber();

获取当前运营商名称及相关描述信息

首先引入官方的CoreTelephony库,然后添加相应的头文件:

1
2
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>

接着使用CTTelephonyNetworkInfo与CTCarrier这两个类获取运营商相关信息,并将其保存到一个CTCarrier对象中:

1
2
3
4
CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = info.subscriberCellularProvider;
NSLog(@”description:%@”,[carrier description]);
NSLog(@”carrier:%@”, carrier.carrierName);

输出为:

1
2
3
4
5
6
7
8
9
CTCarrier (0x1a0200) {
Carrier name: [中国联通]
Mobile Country Code: [460]
Mobile Network Code:[01]
ISO Country Code:[cn]
Allows VOIP? [YES]
}

carrier:中国联通

  1. 用UINavigationController的时候用pushViewController:animated(在调用的函数里面添加如下类似代码)
1
2
teleplayViewController *teleplay = [[teleplayViewController alloc] init];
[self.navigationController pushViewController:teleplay animated:YES];
  1. 其他时候用presentModalViewController:animated(在调用的函数里面添加如下类似代码)
1
[self presentModalViewController:controller animated:YES];

同时不要忘记在另一个视图中调用函数dismissViewControllerAnimated(代码类似如下)

1
[self dismissViewControllerAnimated:YES completion:NULL];
  1. 切换视图一般用不到addSubview

UINavigationController是导航控制器,如果pushViewController的话,会跳转到下一个ViewController,点返回会回到现在这个ViewController;

如果是addSubview的话,其实还是对当前的ViewController操作,只是在当前视图上面又“盖”住了一层视图,其实原来的画面在下面呢,看不到而已。(当然,也可以用insertSubView atIndex那个方法设置放置的层次)

请看下面的实例代码:

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
//点击键盘上的search按钮时调用

- (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar

{

NSString *searchTerm = searchBar.text;

[self handleSearchForTerm:searchTerm];

}


//输入文本实时更新时调用

- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText

{

if (searchText.length == 0) {

[self resetSearch];

[table reloadData];

return;

}



[self handleSearchForTerm:searchText];

}


//cancel按钮点击时调用

- (void) searchBarCancelButtonClicked:(UISearchBar *)searchBar

{

isSearching = NO;

search.text = @"";

[self resetSearch];

[table reloadData];

[searchBar resignFirstResponder];

}


//点击搜索框时调用

- (void) searchBarTextDidBeginEditing:(UISearchBar *)searchBar

{

isSearching = YES;

[table reloadData];

}

UISearchBar上按钮的默认文字为Cancel,如果想改为其他文字请调用以下代码

1
2
3
4
5
6
7
for(id cc in [searchtext subviews]){  
if([cc isKindOfClass:[UIButton class]]){
UIButton *btn = (UIButton *)cc;
[btn setTitle:@"取消" forState:UIControlStateNormal];
}
}

我学过网页制作,多多少少的能理解一下table这个元素,关于ios的uitableview应该也有这些类似的东西,觉得在uitableview中,都能够找与table对应的部分,看下面代码:

MasterViewController.m
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//
// MasterViewController.m
// vlinkagePerson
//
// Created by david on 13-4-14.
// Copyright (c) 2013年 david. All rights reserved.
//

#import "MasterViewController.h"

@interface MasterViewController ()

@end

@implementation MasterViewController

@synthesize navbar,navItem,searchButton,attentionButton,personTable,keys,objects,content;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}

- (void)viewDidLoad
{

[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.keys = [NSArray arrayWithObjects:@"mainTitleKey",@"secondaryTitleKey",@"imageKey",nil];
self.objects = [NSArray arrayWithObjects:@"How",@"Are",@"You",nil];

//表格添加内容
self.content = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];

//创建一个导航栏
self.navbar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];

//创建一个导航栏集合
self.navItem = [[UINavigationItem alloc] initWithTitle:@"艺人列表"];

//在这个集合Item中添加标题,按钮
//style:设置按钮的风格,一共有三种选择
//action:@selector:设置按钮的点击事件
//创建一个左边按钮
self.searchButton = [[UIBarButtonItem alloc] initWithTitle:@"搜索" style:UIBarButtonItemStylePlain target:self action:@selector(searchEvent)];

//创建一个右边按钮
self.attentionButton = [[UIBarButtonItem alloc] initWithTitle:@"我的关注" style:UIBarButtonItemStylePlain target:self action:@selector(attentionList)];

//把导航栏集合添加到导航栏中,设置动画关闭
[self.navbar pushNavigationItem:self.navItem animated:YES];

//把左右两个按钮添加到导航栏集合中去
[self.navItem setLeftBarButtonItem:self.searchButton];
[self.navItem setRightBarButtonItem:self.attentionButton];



//添加UITableView
self.personTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 44, 320, 460)
style:UITableViewStyleGrouped];
[self.personTable setDataSource:self];
[self.personTable setDelegate:self];

//将标题栏中的内容全部添加到主视图当中
[self.view addSubview:self.navbar];
//将表格添加到主视图中
[self.view addSubview:self.personTable];

}

-(void) searchEvent{

}

-(void) attentionList{

}
//Section总数
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
return self.objects;
}

//每个section显示的标题
//设置caption
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return @"大家好";
}


//指定有多少个分区(Section),默认为1
//需要多少个table
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{
return 4;
}

//指定每个分区中有多少行,默认为1
//table的行数
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 2;
}

//绘制Cell
//为每个表格赋值
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];

if (cell == nil) {

cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"];

cell.selectionStyle = UITableViewCellSelectionStyleNone;

}

cell.textLabel.text = [self.content objectForKey:@"mainTitleKey"];

cell.detailTextLabel.text = [self.content objectForKey:@"secondaryTitleKey"];

NSString *path = [[NSBundle mainBundle] pathForResource:[self.content objectForKey:@"imageKey"] ofType:@"png"];

UIImage *theImage = [UIImage imageWithContentsOfFile:path];

cell.imageView.image = theImage;


return cell;
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

iOS NSDictionary 操作代码如下:

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
- (void)loopThrough
{
NSArray * keys=[NSArray arrayWithObjects:@"key1“,@"key2",@"key3",nill];
NSArray *objects=[NSArray arrayWithOjbects:@"how",@"are",@"you",nill];

NSDictionary *dic=[NSDictionary dictionaryWithObjects:objects,forKeys:keys];

//loop 1
for(id key in dic)
{
NSLog(@"key:%@,value:%@",key,[dic objectForKey:key]);
}

//loop 2
NSEnumerator *enumerator;
id key;
enumerator=[dic keyEnumerator];
while((key=[enumerator nextObject]))
{
NSLog(@"key:%@,value:%@",key,objectForKey:key]);
}
}

-(void)testNsMutableDictionary
{
NSMutableDictionary *dic=[NSMutableDictionary dictionaryWithCapacity:30];
//dictionaryWithObjectsAndKeys:[NSMuble numberWithInt:1] @"math1",[NSMuble numberWithInt:2] @"math2"];

[dic setObject:@"one" forKey:@"dog"];
[dic setObject:@"two" forKey:@"cat"];
[dic setValue:[NSString stringWithFormat:@"three"] forKey:@"pig"];


[dic removeObjectForkey:@"cat"];
[dic removeAllObjects];

NSMutableArray arraylist=[[NSMutableArray alloc] init];
[arrarlist addObject:dic];
[dic release];
}
0%