青春时代是一个短暂的美梦,当你醒来时,它早已消失得无影无踪了。
 
今日:0    总帖:356
admin
6454
转自:听雨轩有声电台  原文地址:http://mp.weixin.qq.com/s/TifDO-kE-yhxT3W9wdhCcg “即使是生活在阴沟,我们也有仰望星空的权利。”——阿米尔·汗     他的“仰望星空”,不是文艺青年的风花雪月。他用近乎残酷的方式,剖开印度的伤口,向国人和全世界展示社会的肮脏和弊病。01▼我喜欢一次只做一部电影为这一部倾尽所有一开始,阿米尔·汗并不喜欢电影,即便他出生在电影世家,且年幼成名。阿米尔·汗少年时其实极有运动天赋。那时的他热爱网球,不仅成为马哈拉施特拉邦的网球冠军,还与偶像费德勒打过友谊赛,梦想成为一枚网球小王子。但属于你的迟早会找上门。大学期间,阿米尔友情出演了一位朋友拍摄的无声小短片。大概是冥冥中的召唤,阿米尔说:“拍那部短片让我知道了自己属于那里”。于是毅然从学校辍学,一心投入演艺事业。然而,他的演艺之路走得却并不顺利。1988年,凭借电影《冷暖人间》,阿米尔汗一炮而红,并获得印度最高电影奖Filmfare的最佳新人奖。但接下来签下的九部电影都成绩寥寥。业界人士称他“只有一部电影的奇迹”,预测他将一蹶不振。阿米尔·汗开始在痛苦中自我反省,自我定位,要求自己每年作品绝不超过两部。“我喜欢一次只做一部电影,为这一部倾尽所有。”1992年开始,阿米尔·汗状态开始慢慢恢复。他对演戏的虔诚和认真甚至令人害怕。他曾经把四年时间花在一部戏上,就是《抗暴英雄》。兼为主演和制片人,他不停跑图书馆翻看历史资料,花了一年时间留起长发和八字胡。阿米尔·汗将自己视为“生产工具”,一丝不苟地表现电影的各种细节。和现在的演员喜欢用化妆不同,他电影中的每个样子,都是他本人的真实状态。在拍摄《摔跤吧!爸爸》的时候,先疯狂增肥60斤,再瘦回来,从19岁到51岁,他完美表现出了每一个阶段的体态变化。导演曾经劝他不要那么拼,化妆就好了。但他坚持成为一个真正的胖子:“只有成为胖子,我才能体会到胖子的感受。” 阿米尔·汗习惯在拍电影的时候写下“遗书”。甚至经常担心:如果我死了怎么办?如果我严重受伤怎么办?在每一场拍摄完成后,他会留给工作人员一个字条,上面写着万一他意外死亡,电影接下去的制作计划。在《摔跤吧!爸爸》拍摄期间,他甚至想好了四五个备选演员的名单。他有很好的电影嗅觉和商业眼光,拍出的电影总是叫好又叫座。接连刷新印度电影四个十亿级票房纪录。《摔跤吧,爸爸!》放映的时候,影片结束时,很多影院的观众全体起立,鼓掌致敬。但他却说自己拍电影之前从不想票房,也不会想有多少人去看。“故事是最重要的,如果我要拍一部电影,首先我一定要爱上这个故事,这样我才会有动力。” 也正是因为珍视初心,现如今阿米尔·汗几乎是与高质量电影画上了等号,有网友说:“阿米尔·汗的眼睛里有全世界,有他在,电影质量就有保证。”02▼我无心激化矛盾只为能改变这个时代红了之后的阿米尔·汗开始反思:“教师给社会提供教育,医生提供医疗,艺人能够给这个社会做些什么呢?”他决定用电影来改变世界。他好像带着天然的使命感,这种使命感,让他的电影充满力量。这一次,阿米尔·汗进入大众的视野,是因为《神秘巨星》。这部对准了妇女处境和妇女权益的电影,灵感来自于2012年阿米尔·汗系列节目《真相访谈》。在节目中,阿米尔·汗听到了一个女儿支持妈妈反抗的故事,直接激发了他拍摄《神秘巨星》的想法。在印度,妇女地位低下,每6小时就有一位妇女死于家暴。但印度社会却认为,丈夫殴打妻子,合情合理。但阿米尔·汗决心唤醒这些沉睡的人。从《摔跤吧,爸爸!》到《神秘巨星》,阿尔米·汗鼓励女性去做梦,去争取自己的权利。通过自己的力量,推动社会发生变化,用电影里的故事去影响别人,是阿米尔·汗的梦想。《摔跤吧,爸爸》《神秘巨星》中,他鼓励女性改变自身处境,主张自我权利,追求梦想:“你的胜利不只属于你,还属于千千万万被误解被歧视的女孩。”《三傻大闹宝莱坞》里,他向传统的应试教育发起了尖锐的挑战,告诉每一个人“死记硬背也许能让你通过大学4年,但会毁掉你接下来的40年”。通过《我滴个神啊》,他将宗教议题摆在了大屏幕,告诉大家“爱你,是要给你自由。”宗教也是。这部电影甚至冒犯了印度的政治团体,有印度教徒在公开场合焚烧海报,右翼人士抵制影片上映。阿米尔·汗一次又一次将印度的社会问题展现在大家面前。他明白,身为明星,担负着比别人更重的社会责任。一个人的力量是微小的,阿米尔汗却坚定不移。他深知自己的行为的意义:“我无心激化矛盾,只为能改变这个时代。无论是谁心中,只要有星星之火必将成燎原之势。”03▼没必要为自己祖国被放在聚光灯下而羞耻应该羞耻的是我们的国家在哪一方面有欠缺2012年,阿米尔·汗登上《时代周刊》亚洲版封面。评论写道:“他直面印度的社会弊病,打破了宝莱坞的固有模式,一个演员能够改变一个国家吗?”答案是肯定的。为了《真相访谈》,阿米尔·汗带领团队走访全国,儿童性侵、杀女婴、堕胎、包办婚姻、性别歧视、家庭暴力、种姓制度……这些敏感话题全都成为《真相访谈》的主题。当时很多身边的朋友都劝他:“你做这些对自己根本没好处,还会引起民众反感,降低你的人气。”阿米尔·汗在节目中自白:“我想讨论一些关系印度民生的话题,不责难任何人,不中伤任何人,也不制约任何人。人人都说,伤害我们的人近在咫尺,或许我们都有责任。”但节目一经播出,还是差点遭到印度当局的封禁,然而,仍然有超过6亿人观看了他的节目,他的每一期节目,都引起强烈社会反响和舆论关注,有人把这档节目叫做“印度的眼泪”。 在采访中,阿米尔·汗说:“我不知道这会不会影响到我的从影生涯,但是生而为人,我确实更关心我祖国的现状以及我同胞们的处境。这是一种选择,不是我们的义务,但是如果我们想这样,是可以做到的。”有人评价,阿米尔·汗是印度的“国宝级演员”。而在很多人的心中,阿米尔汗,早已不仅是一位演员。他的使命感和爱国精神,注定使他成为被这个时代铭记的人物。 2013年,阿米尔又作为“100位年度人物”再次登上《时代》封面,列入的并不是“艺术家”类别,而是定位为“先驱者”。这个头衔实至名归。因为他讲过这样的话:“拍摄电影不是用来迎合谁的。其实当你拍摄了一部对自己国家有一定批判意义的电影时,这对国家就有着至关重要的意义。所以批判自己和自己的国家是我们进步的第一步。没必要为自己祖国被放在聚光灯下而羞耻,应该羞耻的是我们的国家在哪一方面有欠缺。” 因为他,我们才知道,除了柴米油烟的生活之外,头顶还有一片浩瀚的星空;在个人的悲喜之外,人生还有更崇高的价值和意义需要守护。因为他,我们才知道,在这个时代,是多么需要阿米尔·汗这样的人。致敬阿米尔·汗。晚安文|崔老板
休闲 1 0 2272天前
admin
6264
作者:Reginald 原文地址:https://bbs.pediy.com/thread-224265.htm一、导出表解析输出表位置,落在了.rdata段,16000【5200】17D70【6F70】从而,可以知道17D70,输出表在磁盘中的偏移是6F70在010里,Ctrl + G,输入6F70这里,先看下导出表的数据结构,40B,typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; // DLL的名称地址 DWORD Base; // 索引基数 DWORD NumberOfFunctions; // 函数地址表大小 DWORD NumberOfNames; // 函数名表大小 == 函数序号表大小 DWORD AddressOfFunctions; // 函数地址表——首地址 DWORD AddressOfNames; // 函数名表——首地址 DWORD AddressOfNameOrdinals; // 函数序号表——首地址 } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;那就从6F70的位置,开始,找40B,如下:00 00 00 0071 DB 67 5A 【时间戳】00 00 【主版本】00 00 【次版本】C0 7D 01 00【DLL名称地址】01 00 00 00 【索引基数】04 00 00 00 【函数地址表大小】04 00 00 00 【函数名表大小 == 函数序号表大小】98 7D 01 00【函数地址表——首地址】A8 7D 01 00 【函数名表——首地址】B8 7D 01 00【函数序号表——首地址】1、看DLL的名称是啥:地址17DC0【6FC0】,找到了我们自己的库dll_00.dll2、再看下函数地址表中的元素,首地址17D98【6F98】,共有4个,地址,4B/个如下所示:3、再来看函数名表中的元素,首地址17DA8【6FA8】,共有4个,地址4B/个这些都是地址值,要找到真正的函数名:17DD0【6FD0】17DD5【6FD5】17DDA【6FDA】17DCB【6FCB】特别注意:函数名表,其实存放的也是地址值,RVA,这个只是我们自己找到的名称,方便起见,直接写的名字4、接下来,看下函数序号表,首地址17DB8【6FB8】,4个,序号,2B/个5、接下来,就分析分析:从这里,也可以看到,序号表里的值,并没有加上索引基数最终,会得到如下结果:6、验证下,我们的结果:成功了;至于,索引基数,还没看到效果呢,————注意看下刚刚的LoadPe里的Ordinal那一列部分代码:#pragma once #define WIN32DLL_EXPORTS #ifdef __cplusplus extern "C" { #endif #ifdef WIN32DLL_EXPORTS #define WIN32DLL_API __declspec(dllexport) #else #define WIN32DLL_API __declspec(dllimport) #endif WIN32DLL_API void Fun1(); WIN32DLL_API void Fun2(); WIN32DLL_API void Fun3(); #ifdef __cplusplus } #endifdef文件LIBRARY; EXPORTS; Fun4;二、导入表解析写一个测试程序,查看导入表RVA输入表位置,落在了.idata段1A000【7400】1A1E8【75E8】共20Btypedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; // 0 for terminating null import descriptor DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) } DUMMYUNIONNAME; DWORD TimeDateStamp; // 0 if not DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; // RVA to IAT } IMAGE_IMPORT_DESCRIPTOR;2C A3 01 00 【OriginalFirstThunk:INT(Import Name Table)导入名称表地址RVA】00 00 00 00 00 00 00 00 54 A4 01 00【DLL名称(地址值)】E0 A0 01 00【IAT(Import Address Table)导入地址表地址RVA】1、首先看下DLL的名字,1A454【7854】2、看下INT(OriginalFirstThunk):1A32C【772C】,全0结尾函数名数组:44 A4 01 00 ————1A444【7844】——————最高位为0,说明是名称导入的,不是序号导入的;3C A4 01 00 ————1A43C【783C】——————4C A4 01 00 ————1A44C【784C】——————34 A4 01 00 ————1A434【7834】——————注意:IAT和INT都指向下面的数据结构,4Btypedef struct _IMAGE_THUNK_DATA32 { union { DWORD ForwarderString; // PBYTE DWORD Function; // PDWORD,导入函数的地址,在加载到内存后,这里才起作用 DWORD Ordinal; // 假如是序号导入的,会用到这里 DWORD AddressOfData; // PIMAGE_IMPORT_BY_NAME,假如是函数名导入的,用到这里,它指向另外一个结构体:PIMGE_IMPORT_BY_NAME } u1; } IMAGE_THUNK_DATA32; // 如果是函数名导入的,AddressOfData会指向下面这个结构体 typedef struct _IMAGE_IMPORT_BY_NAME { WORD Hint; CHAR Name[1]; } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;由上可知,函数名导入的,因此,上面的地址值,就会指向一个PIMAGE_IMPORT_BY_NAME的结构体:【7844】Fun3【783C】Fun2【784C】Fun4【7834】Fun13、看下IAT,1A0E0【74E0】全0结束,IAT和INT一样,都指向IMAGE_THUNK_DATA32结构体,4B可见,最高位都是0,所以,也是名称导入的,另外,还可以发现,这个位置的值,和INT的值是一样的,因此,不再赘述了;44 A4 01 00 3C A4 01 00 4C A4 01 00 34 A4 01 00#include <stdio.h> extern "C" __declspec(dllimport) void Fun1(); extern "C" __declspec(dllimport) void Fun2(); extern "C" __declspec(dllimport) void Fun3(); // 如果是在def中导出的,需要如下声明 void Fun4(); #pragma comment(lib, "../Debug/dll_00.lib") int main(int argc, char** argv) { Fun1(); Fun2(); Fun3(); Fun4(); getchar(); return 0; }三、如果,修改def为LIBRARY; EXPORTS; Fun4 @1;看下导入表里的INT/IAT:可见,这里的一项,最高位为1,序号导入,这个序号,就是dll export的那个序号至此,PE结构中,导入/导出表的介绍结束;PS:I Dare to do sth I feared,作为一枚奋斗青年,也是一枚小白,最近在学习PE结构相关的知识,这篇帖子也算是自己的一个总结;希望能对需要的人以帮助;也期待大神们的更多指导;
其他 1 0 2278天前
admin
5731
DBA操作规范作者:hcymysql  原文转自:http://blog.51cto.com/hcymysql/20614511、涉及业务上的修改/删除数据,在得到业务方、CTO的邮件批准后方可执行,执行前提前做好备份,必要时可逆。2、所有上线需求必须走工单系统,口头通知视为无效。3、在对大表做表结构变更时,如修改字段属性会造成锁表,并会造成从库延迟,从而影响线上业务,必须在凌晨0:00 后业务低峰期执行,另统一用工具 pt-online-schema-change 避免锁表且降低延迟执行时间。使用范例:#pt-online-schema-change --alter="add index IX_id_no(id_no)" \ --no-check-replication-filters --recursion-method=none --user=dba \ --password=123456 D=test,t=t1 --execute对于MongoDB创建索引要在后台创建,避免锁表。使用范例:db.t1.createIndex({idCardNum:1},{background:1})4、所有线上业务库均必须搭建MHA高可用架构,避免单点问题。5、给业务方开权限时,密码要用MD5加密,至少16位。权限如没有特殊要求,均为select查询权限,并做库表级限制。6、删除默认空密码账号。delete from mysql.user where user='' and password=''; flush privileges;7、汇总库开启Audit审计日志功能,出现问题时方可追溯。行为规范8、禁止一个MySQL实例存放多个业务数据库,会造成业务耦合性过高,一旦出现问题会殃及池鱼,增加了定位故障问题的难度。通常采用多实例解决,一个实例一个业务库,互不干扰。9、禁止在主库上执行后台管理和统计类的功能查询,这种复杂类的SQL会造成CPU的升高,进而会影响业务。10、批量清洗数据,需要开发和DBA共同进行审查,应避开业务高峰期时段执行,并在执行过程中观察服务状态。11、促销活动等应提前与DBA当面沟通,进行流量评估,比如提前一周增加机器内存或扩展架构,防止DB出现性能瓶颈。12、禁止在线上做数据库压力测试。基本规范13、禁止在数据库中存储明文密码。14、使用InnoDB存储引擎。支持事务,行级锁,更好的恢复性,高并发下性能更好。InnoDB表避免使用COUNT(*)操作,因内部没有计数器,需要一行一行累加计算,计数统计实时要求较强可以使用memcache或者Redis。15、表字符集统一使用UTF8。不会产生乱码风险。16、所有表和字段都需要添加中文注释。方便他人、方便自己。17、不在数据库中存储图片、文件等大数据。图片、文件更适合于GFS分布式文件系统,数据库里存放超链接即可。18、避免使用存储过程、视图、触发器、事件。MySQL是OLTP应用,最擅长简单的增、删、改、查操作,但对逻辑计算分析类的应用,并不适合,所以这部分的需求最好通过程序上实现。19、避免使用外键,外键用来保护参照完整性,可在业务端实现。外键会导致父表和子表之间耦合,十分影响SQL性能,出现过多的锁等待,甚至会造成死锁。20、对事务一致性要求不高的业务,如日志表等,优先选择存入MongoDB。其自身支持的sharding分片功能,增强了横向扩展的能力,开发不用过多调整业务代码。库表设计规范21、表必须有主键,例如自增主键。这样可以保证数据行是按照顺序写入,对于SAS传统机械式硬盘写入性能更好,根据主键做关联查询的性能也会更好,并且还方便了数据仓库抽取数据。从性能的角度来说,使用UUID作为主键是个最不好的方法,它会使插入变得随机。22、禁止使用分区表。分区表的好处是对于开发来说,不用修改代码,通过后端DB的设置,比如对于时间字段做拆分,就可以轻松实现表的拆分。但这里面涉及一个问题,查询的字段必须是分区键,否则会遍历所有的分区表,并不会带来性能上的提升。此外,分区表在物理结构上仍旧是一张表,此时我们更改表结构,一样不会带来性能上的提升。所以应采用切表的形式做拆分,如程序上需要对历史数据做查询,可通过union all的方式关联查询。另外随着时间的推移,历史数据表不再需要,只需在从库上dump出来,即便捷地迁移至备份机上。字段设计规范23、用DECIMAL代替FLOAT和DOUBLE存储精确浮点数。浮点数的缺点是会引起精度问题,请看下面一个例子:mysql> CREATE TABLE t3 (c1 float(10,2),c2 decimal(10,2)); Query OK, 0 rows affected (0.05 sec) >mysql> insert into t3 values (999998.02, 999998.02); Query OK, 1 row affected (0.01 sec) >mysql> select * from t3; +-----------+-----------+ | c1 | c2 | +-----------+-----------+ | 999998.00 | 999998.02 | +-----------+-----------+ 1 row in set (0.00 sec)可以看到c1列的值由999998.02变成了999998.00,这就是float浮点数类型的不精确性造成的。因此对货币等对精度敏感的数据,应该用定点数表示或存储。24、使用TINYINT来代替ENUM类型。采用enum枚举类型,会存在扩展的问题,例如用户在线状态,如果此时增加了:5表示请勿打扰、6表示开会中、7表示隐身对好友可见,那么增加新的ENUM值要做DDL修改表结构操作了。25、字段长度尽量按实际需要进行分配,不要随意分配一个很大的容量。选择字段的一般原则是保小不保大,能用占用字节少的字段就不用大字段。比如主键,强烈建议用int整型,不用uuid,为什么?省空间啊。空间是什么?空间就是效率!按4个字节和按32个字节定位一条记录,谁快谁慢太明显了。涉及几个表做join时,效果就更明显了。更小的字段类型占用的内存就更少,占用的磁盘空间和磁盘I/O也会更少,而且还会占用更少的带宽。有不少开发人员在设计表字段时,只要是针对数值类型的全部用int,但这不一定合适,就比如用户的年龄,一般来说,年龄大都在1~100岁之间,长度只有3,那么用int就不适合了,可以用tinyint代替。又比如用户在线状态,0表示离线、1表示在线、2表示离开、3表示忙碌、4表示隐身等,其实类似这样的情况,用int都是没有必要的,浪费空间,采用tinyint完全可以满足需要,int占用的是4字节,而tinyint才占用1个字节。int整型有符号(signed)最大值是2147483647,而无符号(unsigned)最大值是4294967295,如果你的需求没有存储负数,那么建议改成有符号(unsigned),可以增加int存储范围。int(10)和int(1)没有什么区别,10和1仅是宽度而已,在设置了zerofill扩展属性的时候有用,例:root@localhost(test)10:39>create table test(id int(10) zerofill,id2 int(1)); Query OK, 0 rows affected (0.13 sec) root@localhost(test)10:39>insert into test values(1,1); Query OK, 1 row affected (0.04 sec) root@localhost(test)10:56>insert into test values(1000000000,1000000000); Query OK, 1 row affected (0.05 sec) root@localhost(test)10:56>select * from test; +------------+------------+ | id | id2 | +------------+------------+ | 0000000001 | 1 | | 1000000000 | 1000000000 | +------------+------------+ 2 rows in set (0.01 sec)26、字段定义为NOT NULL要提供默认值。从应用层角度来看,可以减少程序判断代码,比如你要查询一条记录,如果没默认值,你是不是得先判断该字段对应变量是否被设置,如果没有,你得通过java把该变量置为''或者0,如果设了默认值,判断条件可直接略过。NULL值很难进行查询优化,它会使索引统计更加复杂,还需要MySQL内部进行特殊处理。27、尽可能不使用TEXT、BLOB类型。增加存储空间的占用,读取速度慢。索引规范28、索引不是越多越好,按实际需要进行创建。索引是一把双刃剑,它可以提高查询效率但也会降低插入和更新的速度并占用磁盘空间。适当的索引对应用的性能至关重要,而且在MySQL中使用索引它的速度是极快的。遗憾的是,索引也有相关的开销。每次向表中写入时(如INSERT、UPDATEH或DELETE),如果带有一个或多个索引,那么MySQL也要更新各个索引,这样索引就增加了对各个表的写入操作的开销。只有当某列被用于WHERE子句时,才能享受到索引的性能提升的好处。如果不使用索引,它就没有价值,而且会带来维护上的开销。29、查询的字段必须创建索引。如:1、SELECT、UPDATE、DELETE语句的WHERE条件列;2、多表JOIN的字段。30、不在索引列进行数学运算和函数运算。无法使用索引,导致全表扫描。例:SELECT * FROM t WHERE YEAR(d) &gt;= 2016;由于MySQL不像Oracle那样支持函数索引,即使d字段有索引,也会直接全表扫描。应改为----->SELECT * FROM t WHERE d &gt;= '2016-01-01';31、不在低基数列上建立索引,例如‘性别’。有时候,进行全表浏览要比必须读取索引和数据表更快,尤其是当索引包含的是平均分布的数据集是更是如此。对此典型的例子是性别,它有两个均匀分布的值(男和女)。通过性别需要读取大概一半的行。在种情况下进行全表扫描浏览要更快。32、不使用%前导的查询,如like ‘%xxx’。无法使用索引,导致全表扫描。低效查询 SELECT * FROM t WHERE name LIKE '%de%'; -----> 高效查询 SELECT * FROM t WHERE name LIKE 'de%';33、不使用反向查询,如 not in / not like。无法使用索引,导致全表扫描。34、避免冗余或重复索引。联合索引IX_a_b_c(a,b,c) 相当于 (a) 、(a,b) 、(a,b,c),那么索引 (a) 、(a,b) 就是多余的。SQL设计规范*35、不使用SELECT ,只获取必要的字段。**消耗CPU和IO、消耗网络带宽;无法使用覆盖索引。36、用IN来替换OR。低效查询 SELECT * FROM t WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30; -----> 高效查询 SELECT * FROM t WHERE LOC_IN IN (10,20,30);37、避免数据类型不一致。SELECT * FROM t WHERE id = '19'; -----> SELECT * FROM t WHERE id = 19;38、减少与数据库的交互次数。INSERT INTO t (id, name) VALUES(1,'Bea'); INSERT INTO t (id, name) VALUES(2,'Belle'); INSERT INTO t (id, name) VALUES(3,'Bernice'); -----> INSERT INTO t (id, name) VALUES(1,'Bea'), (2,'Belle'),(3,'Bernice'); Update … where id in (1,2,3,4); Alter table tbl_name add column col1, add column col2;39、拒绝大SQL,拆分成小SQL。低效查询 SELECT * FROM tag JOIN tag_post ON tag_post.tag_id = tag.id JOIN post ON tag_post.post_id = post.id WHERE tag.tag = 'mysql'; 可以分解成下面这些查询来代替 -----> 高效查询 SELECT * FROM tag WHERE tag = 'mysql' SELECT * FROM tag_post WHERE tag_id = 1234 SELECT * FROM post WHERE post_id in (123, 456, 567, 9098, 8904);40、禁止使用order by rand()SELECT * FROM t1 WHERE 1=1 ORDER BY RAND() LIMIT 4; ----> SELECT * FROM t1 WHERE id >= CEIL(RAND()*1000) LIMIT 4;
开发 2 0 2288天前
admin
6614
本文转载自差评(ID:chaping321)  网址:点击访问差友们,平时上网最讨厌看到啥?差评君觉得,应该是这货没啥争议 ↓↓这几乎是互联网时兴以来,每个人都无法避免会遇到的问题。404 这三个数字好像网络之神赐给每个信众的礼物~无论你是亿万富翁还是国家总统,网页打不开就是打不开,啥招也没用。。神说,要有 404,于是有了。。可是,为什么网页打不开,网页上都会显示 404 呢?传说,互联的发明者蒂姆·伯纳斯-李( Tim Berners-Lee )曾经在瑞士的欧洲核研究组织的 404 房间办公,在这个 404 房间有互联网时代的第一个服务器,人们所有的网络请求都会发向那里。大型强子对撞机就是这个欧洲核研究组织的如果你要访问的网络内容不存在,那个服务器就会给你返回 404 Not Found( 404 找不到资源)。。也不知道这个来由是从哪冒出来的,反正越传越广,最后连互联网的发明者罗伯特·卡利奥(Robert Cailliau)都不得不站出来澄清:造谣也要遵循基本法好吧,404 就是因为按顺序轮到 404 了而已。。其实,现在互联网网页都遵循 HTTP 协议(HyperText Transfer Protocol,超文本传输协议),我们每个人需求的网页内容都存储在一个个服务器上,这些储存着 HTML 文件和图像。当服务器检测到有用户给它发送打开网页的请求,服务器就会返回给那个用户一些东西,包括网页状态以及返回的内容(如请求的文件、错误消息、或者其它信息)。一个 HTTP 响应示例上面这个图,就是一个 HTTP 返回的例子,那个红框框起来的,里面有一个东西叫做 “ 返回状态码 ”,这个返回状态码就代表了这个网页状态。譬如,这个例子的网站的返回码是 200,也就是说,这个网站能够被成功访问~2XX 的返回码表示网页请求成功估计大家也看到了,4 开头的状态码就是错误码,返回 4XX 的,这个网页肯定打不开~404 就是其中一种错误的代号。。当服务器找不到用户请求的网页数据,而且并不知道错误原因,才会显示返回一个 404。出现 404 错误之后,网页显示什么内容,全看状态后面跟着什么消息体(看上面倒数第三个图)。有的网站就写着 “ 网页找不到 ”,而有的网站就会埋一些彩蛋~Magic Leap 的 404 网站去年 9 月有网友发现,在 Magic Leap 写着 “ 错误 404 ” 的页面上,一个电灯泡闪烁的频率为摩斯密码,破译后得出的结果正好是鲸鱼座中一颗星星的准确坐标,而这颗星星在每年12月时最明显,网友得出结论: Magic Leap 产品可能会在 12 月正式亮相!果然,Magic Leap 在去年 12 月发布了第一款产品。。(这特么也可以??)那网页出现 404 就一定是因为服务器无法找到用户请求么?天真!也有可能服务器了解你的请求,服务器也有相应的内容,但由于某种奇怪的原因,它被禁止回应你的请求。这时候本来服务器应该回一个 403 和无法返回数据请求的原因,但是它肯定不想被你发现它故意不给你数据,所以,它很有可能就回你一个 404 Not Found,假装自己没有这个数据。。RFC2616 HTTP/1.1 协议里关于 403 的描述不只是 403 ,还有 500 (服务器遇到意外情况,unexpected condition..),都有可能因为服务器懒得跟你解释发生错误的原因,就干脆甩给你一个 404 错误。。是不是突然想明白好多事?就像前面说的一样, 404 只是 HTTP 协议里面的一种返回码,这些返回码能让开发者知道网络连接错误的原因。如果你想在国内看 YouTube 等网站,浏览器会显示 “ 无法访问此网站 ”这种情况下,我们根本无法连接到相应的服务器上,连返回的状态码都没有。。这个完全可以通过浏览器自带的开发者工具看出来~打个比方,使用不了谷歌好像是你的电话线被拔了,电话根本打不出去;而 404 好比是你电话打出去了,可是那头跟你反馈用户无法接通。。所以说上不了谷歌和 404 压根一点关系都没有,是你的网不够科学~HTTP 协议里一共规定了 66 个标准 HTTP 状态返回码,每个都有自己的场景应用,可是有一个是异类。。418 返回码! I'm  a teapot?我是个茶壶??WTF??其实,这是 1998 年愚人节的时候发布的一个搞笑 RFC 协议(RFC 2324 - Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)),超文本咖啡壶控制协议。里面主要围绕一个论题展开:虽然咖啡无处不在,但如果你给一个茶壶发送泡咖啡的请求,那肯定是不行的。。鬼知道这些程序员都在想些什么奇怪的东西。。。如果你一定要给茶壶发送这个请求,茶壶就会给你返回一个 “ I'm a teapot ” 的错误码 418 ,表示我只是一个茶壶,并不能泡咖啡~就这么一个愚人节玩笑,那帮技术宅居然一本正经的写了 10 页文档(网址在这,自己戳:https://tools.ietf.org/html/rfc2324)。。更骚的是,他们还出了续集。。因为之前那个 RFC 2324 超文本咖啡壶控制协议只描写了对咖啡壶的规范,这对只喝茶的人赤裸裸的歧视!所以,2014 年愚人节,他们又发布了 RFC 7168(The Hyper Text Coffee Pot Control Protocol for Tea Efflux Appliances),超文本咖啡壶控制协议之茶版本扩展。就喜欢你们一本正经的胡说八道的样子里面详细的描述了如何使用联网设备,实践各种各样复杂的茶冲泡工艺。连里边放的调味种类分类都细致的不行。。差评君服了。。只提一个小小的建议,貌似这里冲茶的工艺有些偏西方,大部分中国人是没有在茶里面放糖的习惯,所以我建议对泡茶种类做一个划分,什么铁观音、大红袍、普洱之类的。今年愚人节再出一个补充版吧~有人问了, HTTP 返回码就已知的那么几个么?当然不是了。。其实只要程序员有心,他可以自己自定义好多非标准的返回码,只要客户端和服务端都认识就行。当然,国内经常见到的这种图。。这个吧,是你搜的东西不够科学~
其他 1 0 2292天前
admin
5905
作者:Ox9A82    转自看雪论坛   原文地址:http://mp.weixin.qq.com/s/8lXtiwq5BO6PeXlFT57R7gQJavascript语言现在变得越来越流行,各个团队利用了它在各种层面上的支持特性,比如前端、后端、混合的应用程序、嵌入式设备等等。 这篇文章作为这一系列文章的第一篇,旨在深挖 Javascript 的底层工作原理:我们认为通过了解 Javascript 的构建块以及了解它们是怎么一起工作的可以使得我们写出更好的代码和app。我们还将分享构建 SessionStack 时的一些经验法则,这是一个轻量级的 JavaScript 应用程序,它必须保持强大且高性能才能保持竞争力。 如GitHut统计中所示,JavaScript在GitHub中的活动存储库和总推送量方面位居前列。相比其他类别也不落后。如果项目越来越依赖于JavaScript,这意味着开发人员必须利用语言和生态系统提供的所有内容,深入了解内部,才能构建出令人惊叹的软件。 事实证明,有很多开发人员每天都在使用JavaScript,但并不知道底层会发生什么。概览几乎每个人都听说过V8引擎这个概念,大多数人都知道JavaScript是单线程的,或者它使用的是回调队列。在这篇文章中,我们将详细介绍所有这些概念,并解释JavaScript如何运行。通过了解这些细节,您将能够编写更好的非阻塞应用程序,并且学会正确使用所提供的API。 如果你对JavaScript比较陌生,那么这篇博文将帮助你理解为什么说JavaScript与其他语言相比是比较怪异的。 如果你是一位经验丰富的JavaScript开发人员,我希望能够提供一些关于你每天都在使用的JavaScript Runtime的实际工作情况的全新理解。Javascript引擎关于JS引擎一个最著名的例子就是谷歌的V8引擎。目前Chrome和Node.js中使用的就是V8引擎。下面是一个简单的视图:引擎包含两个主要部件:堆内存 - 这是发生内存分配的地方调用栈 - 这是代码执行时的栈帧运行时几乎所有的JS开发者在浏览器中都使用过API(例如“setTimeout”)。但是,这些API不是由引擎提供的。 那么这些API从哪里来呢? 事实证明,现实情况有些复杂。如图所示,可以发现其实我们除了引擎之外还依赖其他很多东西。像DOM、AJAX、setTimeout等等这些东西是由浏览器提供的,被称为Web API。 然后,我们就有了非常流行的事件循环和回调队列。调用栈JavaScript是一种单线程语言,这意味着它只有一个调用栈。因此,它同一时间只可以做一件事。调用栈是一个数据结构,它大致的记录了我们位于程序中的哪个位置。 如果我们进入一个函数,就会把它放在栈的顶部。如果我们从一个函数返回,那么会弹出栈的顶部。 我们来看一个例子。如下面的代码:function multiply(x, y) { return x * y; } function printSquare(x) { var s = multiply(x, x); console.log(s); } printSquare(5);当引擎开始执行这段代码之前,调用栈是空的。之后的步骤如下:调用栈中的每个条目都称为是栈帧。 这也是在发生异常时进行堆栈跟踪的方法 - 这大体上是异常发生时的调用栈的状态。看看下面的代码:function foo() { throw new Error('SessionStack will help you resolve crashes :)'); } function bar() { foo(); } function start() { bar(); } start();如果这是在Chrome中执行的(假设代码在一个名为foo.js的文件中),那么会产生下面的堆栈跟踪:“栈上溢(Blowing the stack)” - 当达到最大调用栈大小时就会发生这种情况。 这可能会很容易的发生,特别是使用递归的情况下。看看这个示例代码:function foo() { foo(); } foo();当引擎开始执行这个代码时,它首先调用函数“foo”。然而,这个函数是递归的,并且没有任何终止条件。 所以在执行的步骤中,同一个函数会一次又一次地添加到调用栈中。 它看起来像这样:在某些情况下,调用栈中函数调用的数量超出了调用栈的实际大小,浏览器通过抛出一个错误(如下所示)来采取行动:在单线程上运行代码可能会更容易一些,因为不必担心多线程环境中出现的复杂场景,例如死锁。 但是在单线程上运行也是非常有限的。 由于JS只有一个调用栈,所以当运行很慢时会发生什么?并发和事件循环如果在调用栈中的函数调用需要花费大量时间才能进行处理,会发生什么? 例如,假设你想在浏览器中使用JS进行一些复杂的图像转换。 你可能会奇怪 - 为什么这是个问题?但是问题是,虽然调用栈有执行的功能,但此时浏览器实际上不能做其他的任何事情 - 它被阻塞了。 这意味着浏览器无法进行渲染,也不能运行任何其他代码,它只是卡住了。 如果你想在你的应用程序中实现流畅的UI,这就会产生问题。 并且这还不是唯一的问题。 一旦浏览器开始在调用栈中处理如此多的任务,它可能会停止响应相当长的时间。 而且大多数浏览器会通过抛出错误来应对,询问是否要终止网页。所以这不是一个好的用户体验,是吗? 那么,我们如何执行大量代码而不会阻塞UI使浏览器无法响应呢?解决方案是异步回调。这将在“JavaScript底层是如何工作的”教程的第2部分中更详细地解释。 同时,如果在JS应用遇到了难以复制和理解问题,请查看SessionStack。 SessionStack记录Web应用程序中的所有内容:所有的DOM更改,用户交互,JavaScript异常,堆栈跟踪,失败的网络请求和调试消息。借助SessionStack,可以将视频中的问题重放为视频,并查看用户发生的所有事情。
开发 3 0 2292天前
admin
5075
一、什么是CURL?cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP、FTP、TELNET等。最爽的是,PHP也支持 cURL 库。使用PHP的cURL库可以简单和有效地去抓网页。你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了。无论是你想从从一个链接上取部分数据,或是取一个XML文件并把其导入数据库,那怕就是简单的获取网页内容,cURL 是一个功能强大的PHP库。二、CURL函数库。curl_close — 关闭一个curl会话curl_copy_handle — 拷贝一个curl连接资源的所有内容和参数curl_errno — 返回一个包含当前会话错误信息的数字编号curl_error — 返回一个包含当前会话错误信息的字符串curl_exec — 执行一个curl会话curl_getinfo — 获取一个curl连接资源句柄的信息curl_init — 初始化一个curl会话curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄资源curl_multi_close — 关闭一个批处理句柄资源curl_multi_exec — 解析一个curl批处理句柄curl_multi_getcontent — 返回获取的输出的文本流curl_multi_info_read — 获取当前解析的curl的相关传输信息curl_multi_init — 初始化一个curl批处理句柄资源curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源curl_multi_select — Get all the sockets associated with the cURL extension, which can then be “selected”curl_setopt_array — 以数组的形式为一个curl设置会话参数curl_setopt — 为一个curl设置会话参数curl_version — 获取curl相关的版本信息curl_init()函数的作用初始化一个curl会话,curl_init()函数唯一的一个参数是可选的,表示一个url地址。curl_exec()函数的作用是执行一个curl会话,唯一的参数是curl_init()函数返回的句柄。curl_close()函数的作用是关闭一个curl会话,唯一的参数是curl_init()函数返回的句柄。三、PHP建立CURL请求的基本步骤①:初始化curl_init()②:设置属性curl_setopt().有一长串cURL参数可供设置,它们能指定URL请求的各个细节。③:执行并获取结果curl_exec()④:释放句柄curl_close()四、CURL实现GET和POST①:GET方式实现<?php //初始化 $curl = curl_init(); //设置抓取的url curl_setopt($curl, CURLOPT_URL, 'http://www.baidu.com'); //设置头文件的信息作为数据流输出 curl_setopt($curl, CURLOPT_HEADER, 1); //设置获取的信息以文件流的形式返回,而不是直接输出。 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //执行命令 $data = curl_exec($curl); //关闭URL请求 curl_close($curl); //显示获得的数据 print_r($data); ?>运行结果:②:POST方式实现<?php //初始化 $curl = curl_init(); //设置抓取的url curl_setopt($curl, CURLOPT_URL, 'http://www.baidu.com'); //设置头文件的信息作为数据流输出 curl_setopt($curl, CURLOPT_HEADER, 1); //设置获取的信息以文件流的形式返回,而不是直接输出。 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //设置post方式提交 curl_setopt($curl, CURLOPT_POST, 1); //设置post数据 $post_data = array( "username" => "coder", "password" => "12345" ); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); //执行命令 $data = curl_exec($curl); //关闭URL请求 curl_close($curl); //显示获得的数据 print_r($data); ?>③:如果获得的数据时json格式的,使用json_decode函数解释成数组。$output_array = json_decode($output,true);如果使用json_decode($output)解析的话,将会得到object类型的数据。五、我自己封装的一个函数//参数1:访问的URL,参数2:post数据(不填则为GET),参数3:提交的$cookies,参数4:是否返回$cookies function curl_request($url,$post='',$cookie='', $returnCookie=0){ $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)'); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl, CURLOPT_AUTOREFERER, 1); curl_setopt($curl, CURLOPT_REFERER, "http://XXX"); if($post) { curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post)); } if($cookie) { curl_setopt($curl, CURLOPT_COOKIE, $cookie); } curl_setopt($curl, CURLOPT_HEADER, $returnCookie); curl_setopt($curl, CURLOPT_TIMEOUT, 10); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($curl); if (curl_errno($curl)) { return curl_error($curl); } curl_close($curl); if($returnCookie){ list($header, $body) = explode("\r\n\r\n", $data, 2); preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches); $info['cookie'] = substr($matches[1][0], 1); $info['content'] = $body; return $info; }else{ return $data; } }附可选参数说明:第一类:对于下面的这些option的可选参数,value应该被设置一个bool类型的值:选项可选value值备注CURLOPT_AUTOREFERER当根据Location:重定向时,自动设置header中的Referer:信息。CURLOPT_BINARYTRANSFER在启用CURLOPT_RETURNTRANSFER的时候,返回原生的(Raw)输出。CURLOPT_COOKIESESSION启用时curl会仅仅传递一个session cookie,忽略其他的cookie,默认状况下cURL会将所有的cookie返回给服务端。session cookie是指那些用来判断服务器端的session是否有效而存在的cookie。CURLOPT_CRLF启用时将Unix的换行符转换成回车换行符。CURLOPT_DNS_USE_GLOBAL_CACHE启用时会启用一个全局的DNS缓存,此项为线程安全的,并且默认启用。CURLOPT_FAILONERROR显示HTTP状态码,默认行为是忽略编号小于等于400的HTTP信息。CURLOPT_FILETIME启用时会尝试修改远程文档中的信息。结果信息会通过 curl_getinfo()函数的CURLINFO_FILETIME选项返回。curl_getinfo().CURLOPT_FOLLOWLOCATION启用时会将服务器服务器返回的”Location: “放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。CURLOPT_FORBID_REUSE在完成交互以后强迫断开连接,不能重用。CURLOPT_FRESH_CONNECT强制获取一个新的连接,替代缓存中的连接。CURLOPT_FTP_USE_EPRT启用时当FTP下载时,使用EPRT (或 LPRT)命令。设置为FALSE时禁用EPRT和LPRT,使用PORT命令 only.CURLOPT_FTP_USE_EPSV启用时,在FTP传输过程中回复到PASV模式前首先尝试EPSV命令。设置为FALSE时禁用EPSV命令。CURLOPT_FTPAPPEND启用时追加写入文件而不是覆盖它。CURLOPT_FTPASCIICURLOPT_TRANSFERTEXT的别名。CURLOPT_FTPLISTONLY启用时只列出FTP目录的名字。CURLOPT_HEADER启用时会将头文件的信息作为数据流输出。CURLINFO_HEADER_OUT启用时追踪句柄的请求字符串。从 PHP 5.1.3 开始可用。CURLINFO_前缀是故意的(intentional)。CURLOPT_HTTPGET启用时会设置HTTP的method为GET,因为GET是默认是,所以只在被修改的情况下使用。CURLOPT_HTTPPROXYTUNNEL启用时会通过HTTP代理来传输。CURLOPT_MUTE启用时将cURL函数中所有修改过的参数恢复默认值。CURLOPT_NETRC在连接建立以后,访问~/.netrc文件获取用户名和密码信息连接远程站点。CURLOPT_NOBODY启用时将不对HTML中的BODY部分进行输出。CURLOPT_NOPROGRESS启用时关闭curl传输的进度条,此项的默认设置为启用。Note:PHP自动地设置这个选项为TRUE,这个选项仅仅应当在以调试为目的时被改变。CURLOPT_NOSIGNAL启用时忽略所有的curl传递给php进行的信号。在SAPI多线程传输时此项被默认启用。cURL 7.10时被加入。CURLOPT_POST启用时会发送一个常规的POST请求,类型为:application/x-www-form-urlencoded,就像表单提交的一样。CURLOPT_PUT启用时允许HTTP发送文件,必须同时设置CURLOPT_INFILE和CURLOPT_INFILESIZE。CURLOPT_RETURNTRANSFER将 curl_exec()获取的信息以文件流的形式返回,而不是直接输出。CURLOPT_SSL_VERIFYPEER禁用后cURL将终止从服务端进行验证。使用CURLOPT_CAINFO选项设置证书使用CURLOPT_CAPATH选项设置证书目录 如果CURLOPT_SSL_VERIFYPEER(默认值为2)被启用,CURLOPT_SSL_VERIFYHOST需要被设置成TRUE否则设置为FALSE。自cURL 7.10开始默认为TRUE。从cURL 7.10开始默认绑定安装。CURLOPT_TRANSFERTEXT启用后对FTP传输使用ASCII模式。对于LDAP,它检索纯文本信息而非HTML。在Windows系统上,系统不会把STDOUT设置成binary模式。CURLOPT_UNRESTRICTED_AUTH在使用CURLOPT_FOLLOWLOCATION产生的header中的多个locations中持续追加用户名和密码信息,即使域名已发生改变。CURLOPT_UPLOAD启用后允许文件上传。CURLOPT_VERBOSE启用时会汇报所有的信息,存放在STDERR或指定的CURLOPT_STDERR中。第二类:对于下面的这些option的可选参数,value应该被设置一个integer类型的值:选项可选value值备注CURLOPT_BUFFERSIZE每次获取的数据中读入缓存的大小,但是不保证这个值每次都会被填满。在cURL 7.10中被加入。CURLOPT_CLOSEPOLICY不是CURLCLOSEPOLICY_LEAST_RECENTLY_USED就是CURLCLOSEPOLICY_OLDEST,还存在另外三个CURLCLOSEPOLICY_,但是cURL暂时还不支持。CURLOPT_CONNECTTIMEOUT在发起连接前等待的时间,如果设置为0,则无限等待。CURLOPT_CONNECTTIMEOUT_MS尝试连接等待的时间,以毫秒为单位。如果设置为0,则无限等待。在cURL 7.16.2中被加入。从PHP 5.2.3开始可用。CURLOPT_DNS_CACHE_TIMEOUT设置在内存中保存DNS信息的时间,默认为120秒。CURLOPT_FTPSSLAUTHFTP验证方式:CURLFTPAUTH_SSL (首先尝试SSL),CURLFTPAUTH_TLS (首先尝试TLS)或CURLFTPAUTH_DEFAULT (让cURL自动决定)。在cURL 7.12.2中被加入。CURLOPT_HTTP_VERSIONCURL_HTTP_VERSION_NONE (默认值,让cURL自己判断使用哪个版本),CURL_HTTP_VERSION_1_0 (强制使用 HTTP/1.0)或CURL_HTTP_VERSION_1_1 (强制使用 HTTP/1.1)。CURLOPT_HTTPAUTH使用的HTTP验证方法,可选的值有:CURLAUTH_BASIC、CURLAUTH_DIGEST、CURLAUTH_GSSNEGOTIATE、CURLAUTH_NTLM、CURLAUTH_ANY和CURLAUTH_ANYSAFE。可以使用|位域(或)操作符分隔多个值,cURL让服务器选择一个支持最好的值。CURLAUTH_ANY等价于CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM.CURLAUTH_ANYSAFE等价于CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM.CURLOPT_INFILESIZE设定上传文件的大小限制,字节(byte)为单位。CURLOPT_LOW_SPEED_LIMIT当传输速度小于CURLOPT_LOW_SPEED_LIMIT时(bytes/sec),PHP会根据CURLOPT_LOW_SPEED_TIME来判断是否因太慢而取消传输。CURLOPT_LOW_SPEED_TIME当传输速度小于CURLOPT_LOW_SPEED_LIMIT时(bytes/sec),PHP会根据CURLOPT_LOW_SPEED_TIME来判断是否因太慢而取消传输。CURLOPT_MAXCONNECTS允许的最大连接数量,超过是会通过CURLOPT_CLOSEPOLICY决定应该停止哪些连接。CURLOPT_MAXREDIRS指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的。CURLOPT_PORT用来指定连接端口。(可选项)CURLOPT_PROTOCOLSCURLPROTO_*的位域指。如果被启用,位域值会限定libcurl在传输过程中有哪些可使用的协议。这将允许你在编译libcurl时支持众多协议,但是限制只是用它们中被允许使用的一个子集。默认libcurl将会使用全部它支持的协议。参见CURLOPT_REDIR_PROTOCOLS.可用的协议选项为:CURLPROTO_HTTP、CURLPROTO_HTTPS、CURLPROTO_FTP、CURLPROTO_FTPS、CURLPROTO_SCP、CURLPROTO_SFTP、CURLPROTO_TELNET、CURLPROTO_LDAP、CURLPROTO_LDAPS、CURLPROTO_DICT、CURLPROTO_FILE、CURLPROTO_TFTP、CURLPROTO_ALL在cURL 7.19.4中被加入。CURLOPT_PROXYAUTHHTTP代理连接的验证方式。使用在CURLOPT_HTTPAUTH中的位域标志来设置相应选项。对于代理验证只有CURLAUTH_BASIC和CURLAUTH_NTLM当前被支持。在cURL 7.10.7中被加入。CURLOPT_PROXYPORT代理服务器的端口。端口也可以在CURLOPT_PROXY中进行设置。CURLOPT_PROXYTYPE不是CURLPROXY_HTTP (默认值) 就是CURLPROXY_SOCKS5。在cURL 7.10中被加入。CURLOPT_REDIR_PROTOCOLSCURLPROTO_*中的位域值。如果被启用,位域值将会限制传输线程在CURLOPT_FOLLOWLOCATION开启时跟随某个重定向时可使用的协议。这将使你对重定向时限制传输线程使用被允许的协议子集默认libcurl将会允许除FILE和SCP之外的全部协议。这个和7.19.4预发布版本种无条件地跟随所有支持的协议有一些不同。关于协议常量,请参照CURLOPT_PROTOCOLS。在cURL 7.19.4中被加入。CURLOPT_RESUME_FROM在恢复传输时传递一个字节偏移量(用来断点续传)。CURLOPT_SSL_VERIFYHOST1 检查服务器SSL证书中是否存在一个公用名(common name)。译者注:公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。2 检查公用名是否存在,并且是否与提供的主机名匹配。CURLOPT_SSLVERSION使用的SSL版本(2 或 3)。默认情况下PHP会自己检测这个值,尽管有些情况下需要手动地进行设置。CURLOPT_TIMECONDITION如果在CURLOPT_TIMEVALUE指定的某个时间以后被编辑过,则使用CURL_TIMECOND_IFMODSINCE返回页面,如果没有被修改过,并且CURLOPT_HEADER为true,则返回一个”304 Not Modified”的header,        CURLOPT_HEADER为false,则使用CURL_TIMECOND_IFUNMODSINCE,默认值为CURL_TIMECOND_IFUNMODSINCE。CURLOPT_TIMEOUT设置cURL允许执行的最长秒数。CURLOPT_TIMEOUT_MS设置cURL允许执行的最长毫秒数。在cURL 7.16.2中被加入。从PHP 5.2.3起可使用。CURLOPT_TIMEVALUE设置一个CURLOPT_TIMECONDITION使用的时间戳,在默认状态下使用的是CURL_TIMECOND_IFMODSINCE。第三类:对于下面的这些option的可选参数,value应该被设置一个string类型的值:选项可选value值备注CURLOPT_CAINFO一个保存着1个或多个用来让服务端验证的证书的文件名。这个参数仅仅在和CURLOPT_SSL_VERIFYPEER一起使用时才有意义。 .CURLOPT_CAPATH一个保存着多个CA证书的目录。这个选项是和CURLOPT_SSL_VERIFYPEER一起使用的。CURLOPT_COOKIE设定HTTP请求中”Cookie: “部分的内容。多个cookie用分号分隔,分号后带一个空格(例如, “fruit=apple; colour=red”)。CURLOPT_COOKIEFILE包含cookie数据的文件名,cookie文件的格式可以是Netscape格式,或者只是纯HTTP头部信息存入文件。CURLOPT_COOKIEJAR连接结束后保存cookie信息的文件。CURLOPT_CUSTOMREQUEST使用一个自定义的请求信息来代替”GET”或”HEAD”作为HTTP请求。这对于执行”DELETE” 或者其他更隐蔽的HTTP请求。有效值如”GET”,”POST”,”CONNECT”等等。也就是说,不要在这里输入整个HTTP请求。例如输入”GET /index.html HTTP/1.0\r\n\r\n”是不正确的。Note:在确定服务器支持这个自定义请求的方法前不要使用。CURLOPT_EGDSOCKET类似CURLOPT_RANDOM_FILE,除了一个Entropy Gathering Daemon套接字。CURLOPT_ENCODINGHTTP请求头中”Accept-Encoding: “的值。支持的编码有”identity”,”deflate”和”gzip”。如果为空字符串””,请求头会发送所有支持的编码类型。在cURL 7.10中被加入。CURLOPT_FTPPORT这个值将被用来获取供FTP”POST”指令所需要的IP地址。”POST”指令告诉远程服务器连接到我们指定的IP地址。这个字符串可以是纯文本的IP地址、主机名、一个网络接口名(UNIX下)或者只是一个’-’来使用默认的IP地址。CURLOPT_INTERFACE网络发送接口名,可以是一个接口名、IP地址或者是一个主机名。CURLOPT_KRB4LEVELKRB4 (Kerberos 4) 安全级别。下面的任何值都是有效的(从低到高的顺序):”clear”、”safe”、”confidential”、”private”.。如果字符串和这些都不匹配,将使用”private”。这个选项设置为NULL时将禁用KRB4 安全认证。目前KRB4 安全认证只能用于FTP传输。CURLOPT_POSTFIELDS全部数据使用HTTP协议中的”POST”操作来发送。要发送文件,在文件名前面加上@前缀并使用完整路径。这个参数可以通过urlencoded后的字符串类似’para1=val1¶2=val2&…’或使用一个以字段名为键值,字段数据为值的数组。如果value是一个数组,Content-Type头将会被设置成multipart/form-data。CURLOPT_PROXYHTTP代理通道。CURLOPT_PROXYUSERPWD一个用来连接到代理的”[username]:[password]“格式的字符串。CURLOPT_RANDOM_FILE一个被用来生成SSL随机数种子的文件名。CURLOPT_RANGE以”X-Y”的形式,其中X和Y都是可选项获取数据的范围,以字节计。HTTP传输线程也支持几个这样的重复项中间用逗号分隔如”X-Y,N-M”。CURLOPT_REFERER在HTTP请求头中”Referer: “的内容。CURLOPT_SSL_CIPHER_LIST一个SSL的加密算法列表。例如RC4-SHA和TLSv1都是可用的加密列表。CURLOPT_SSLCERT一个包含PEM格式证书的文件名。CURLOPT_SSLCERTPASSWD使用CURLOPT_SSLCERT证书需要的密码。CURLOPT_SSLCERTTYPE证书的类型。支持的格式有”PEM” (默认值), “DER”和”ENG”。在cURL 7.9.3中被加入。CURLOPT_SSLENGINE用来在CURLOPT_SSLKEY中指定的SSL私钥的加密引擎变量。CURLOPT_SSLENGINE_DEFAULT用来做非对称加密操作的变量。CURLOPT_SSLKEY包含SSL私钥的文件名。CURLOPT_SSLKEYPASSWD在CURLOPT_SSLKEY中指定了的SSL私钥的密码。Note:由于这个选项包含了敏感的密码信息,记得保证这个PHP脚本的安全。CURLOPT_SSLKEYTYPECURLOPT_SSLKEY中规定的私钥的加密类型,支持的密钥类型为”PEM”(默认值)、”DER”和”ENG”。CURLOPT_URL需要获取的URL地址,也可以在 curl_init()函数中设置。CURLOPT_USERAGENT在HTTP请求中包含一个”User-Agent: “头的字符串。CURLOPT_USERPWD传递一个连接中需要的用户名和密码,格式为:”[username]:[password]“。第四类对于下面的这些option的可选参数,value应该被设置一个数组:选项可选value值备注CURLOPT_HTTP200ALIASES200响应码数组,数组中的响应吗被认为是正确的响应,否则被认为是错误的。在cURL 7.10.3中被加入。CURLOPT_HTTPHEADER一个用来设置HTTP头字段的数组。使用如下的形式的数组进行设置: array(‘Content-type: text/plain’, ‘Content-length: 100′)CURLOPT_POSTQUOTE在FTP请求执行完成后,在服务器上执行的一组FTP命令。CURLOPT_QUOTE一组先于FTP请求的在服务器上执行的FTP命令。对于下面的这些option的可选参数,value应该被设置一个流资源 (例如使用 fopen()):选项可选value值CURLOPT_FILE设置输出文件的位置,值是一个资源类型,默认为STDOUT (浏览器)。CURLOPT_INFILE在上传文件的时候需要读取的文件地址,值是一个资源类型。CURLOPT_STDERR设置一个错误输出地址,值是一个资源类型,取代默认的STDERR。CURLOPT_WRITEHEADER设置header部分内容的写入的文件地址,值是一个资源类型。对于下面的这些option的可选参数,value应该被设置为一个回调函数名:选项可选value值CURLOPT_HEADERFUNCTION设置一个回调函数,这个函数有两个参数,第一个是cURL的资源句柄,第二个是输出的header数据。header数据的输出必须依赖这个函数,返回已写入的数据大小。CURLOPT_PASSWDFUNCTION设置一个回调函数,有三个参数,第一个是cURL的资源句柄,第二个是一个密码提示符,第三个参数是密码长度允许的最大值。返回密码的值。CURLOPT_PROGRESSFUNCTION设置一个回调函数,有三个参数,第一个是cURL的资源句柄,第二个是一个文件描述符资源,第三个是长度。返回包含的数据。CURLOPT_READFUNCTION拥有两个参数的回调函数,第一个是参数是会话句柄,第二是HTTP响应头信息的字符串。使用此函数,将自行处理返回的数据。返回值为数据大小,以字节计。返回0代表EOF信号。CURLOPT_WRITEFUNCTION拥有两个参数的回调函数,第一个是参数是会话句柄,第二是HTTP响应头信息的字符串。使用此回调函数,将自行处理响应头信息。响应头信息是整个字符串。设置返回值为精确的已写入字符串长度。发生错误时传输线程终止。本文链接:http://www.blogfshare.com/php-curl-get-post.html
开发 2 0 2296天前
admin
7117
原文地址:http://blog.csdn.net/ibingow/article/details/7104346 经常碰到某些程序崩溃时弹出带红色叉叉的错误窗口或者是叫你选择调试或关闭的窗口,很碍眼。不过平时也没去理它,点掉就好。    今天客户反映我们的程序崩溃后就起不来了,其实我们为了方便无人化管理,做了一个守护进程。如果程序异常退出就会重启那个程序,这在linux下没问题,程序崩溃了就直接退出返回非零值,但是window就bug了,搞不好就给你弹出个错误对话框,你不点掉其实程序就没退出,守护进程就不知道这个程序是否崩溃,于是这个程序就永远死在那个窗口上了。现在这不仅碍眼,还碍事!于是着手摆平之。    先是晚上搜到可以修改注册表来组织程序或系统的弹出对话框,参考:http://technet.microsoft.com/en-us/library/cc976167.aspx。不过这不可行,我们只是希望我们的程序不会弹出对话框,尽量少改系统的。而且试了下发现还是会弹出来,就是那个werfault.exe进程,xp下可能不会。算了,这条路不走了。    用代码肯定也有办法解决。你看人家qq什么的奔溃了有弹出的都是自家的温馨提示,我们不需要温馨提示,只要返回非零值就好。    万能的Google一下子就搜出结果来了。原来Microsoft对c和c++进行了扩展,支持异常处理,而且貌似标准c++里的异常处理也是它的一个封装。Microsoft的异常处理函数是__try,__except。先试了这么个简单的例子 #include <windows.h> #include <excpt.h> #include <stdio.h> #define CRASH_SILENTLY 1 #if defined(_MSC_VER) && CRASH_SILENTLY #include <excpt.h> #define Q_TRY_BEGIN __try { #define Q_TRY_END } //EXCEPTION_EXECUTE_HANDLER #define Q_EXCEPT __except(EXCEPTION_EXECUTE_HANDLER) { \ printf("Shit happens!\n");fflush(NULL); \ return 1;} #else #define Q_TRY_BEGIN #define Q_TRY_END #define Q_EXCEPT #endif int main(int, char**) { Q_TRY_BEGIN int *a = 0; *a = 0; Q_TRY_END Q_EXCEPT printf("Exiting 0...\n"); fflush(NULL); return 0; }     如果把CRASH_SILENTLY定义为0,那么在程序崩溃就会弹出对话框,设为一就只打印Shit happens!然后就返回。    __except的参数有三种,详细内容见http://msdn.microsoft.com/en-us/library/s58ftw19%28v=vs.80%29.aspx,我就不抄了。    其实为什么系统会弹出这么一个对话框呢?其实在vc运行库中顶层函数也用了__try, __except的异常捕获机制。不知您看了__except的参数了没,我的示例程序里是EXCEPTION_EXECUTE_HANDLER,表示异常被识别,就在__except后面的代码段进行异常处理。如果是EXCEPTION_CONTINUE_SEARCH,那么异常会继续被派发到外层,这最外层就是vc库,vc库它的处理手段就是碍眼又碍事的对话框!    上面这个程序只是演示用的,很简单。然后我就满怀希望地对公司的程序也做了类似的处理,然后悲剧发生了,竟然编译都通不过!编译错误是C2712:cannot use __try in functions that require object unwinding。于是又google了一番。msdn真的很棒,资料丰富,这下有时msdn上的方法解决的。详见http://msdn.microsoft.com/en-us/library/xwtb73ad%28VS.80%29.aspx    With /EHsc, a function with structured exception handling cannot have objects that require unwinding (destruction).    我们的程序里出现了有析构函数的对象,同时编译参数又有/EHsc,于是出现编译错误了。可以参考下这篇文章http://se.csai.cn/ExpertEyes/No163.htm    作为一个例子,如果我们把上面的程序改成下面的就可能出现上述问题class Shit { public: Shit() {} ~Shit() {} }; int main(int, char**) { Q_TRY_BEGIN Shit s; int *a = 0; *a = 0; Q_TRY_END Q_EXCEPT printf("Exiting 0...\n"); fflush(NULL); return 0; }     msdn提出3种方案,允许我复制下    Move code that requires SEH to another function.    Rewrite functions that use SEH to avoid the use of local variables and parameters that have destructors. Do not use SEH in constructors or destructors.    Compile without /EHsc.    显然前两种办法对代码改动太大了,不可取,那么就去掉/EHsc吧。由于我是用Qt写程序,有些编译选项都是默认设好的,我在pro文件里尝试定义QMAKE_CXXFLAGS竟然无效,不是很清楚为什么。一般是在qmake.config和prf文件里里可以找到。qmake.conf里找到相关的两行 QMAKE_CXXFLAGS_STL_ON = -EHsc QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc 在我们工程文件里直接设这两个为空竟然可以。后来又看了下Makefile,发现生成Makefile会依赖exceptions.prf, stl.prf,而这两个会加入上面两个变量,比如stl.prf:CONFIG -= stl_off QMAKE_CFLAGS *= $QMAKE_CFLAGS_STL_ON QMAKE_CXXFLAGS *= $QMAKE_CXXFLAGS_STL_ON 于是在工程文件中加入CONFIG -= exceptions stl 或者CONFIG += exceptions_off stl_off 就解决问题了,而且比之前的方法优雅。看看Makefile里相关代码变成了$(QMAKE) -spec ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\default CONFIG+=release -o Makefile pvplayer.pro ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf: ..\config.pri: ..\pvcommon\pvcommon.pri: ..\config.pri: ..\log4qt\log4qt.pri: ..\config.pri: ..\qextserialport\qextserialport.pri: ..\config.pri: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\release.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\shared.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl_off.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions_off.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf: ..\..\..\..\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf: e:\QtSDK\Desktop\Qt\4.7.4\msvc2008\lib\qtmain.prl:     好,至此已经把弹出对话框的问题解决了。不过还值得深入研究,目前只是做到了会用的程度。还有就是linux下或其他平台上有无类似处理还没调查。应该也有,因为最近linux下的thunderbird一启动就崩溃,弹出对话框。有空继续研究。参考文献:http://msdn.microsoft.com/en-us/library/s58ftw19%28v=vs.80%29.aspxhttp://msdn.microsoft.com/en-us/library/xwtb73ad%28VS.80%29.aspxUse /EHa if you want to catch an exception raised with something other than a throw.http://msdn.microsoft.com/en-us/library/1deeycx5%28VS.80%29.aspxhttp://blog.csdn.net/bichenggui/article/details/4536534http://se.csai.cn/ExpertEyes/No163.htm
开发 2 0 2296天前
admin
6581
      原文地址:https://mp.weixin.qq.com/s/NnZQLuDDTSEqKuKXs_WvLg      相信大家最近都已经知道了这个Intel CPU的漏洞,目前微软、Linux等都已经针对各自发布了相对应的补丁,那么如何检查是否已经安装了呢      微软还发布了一套例程,可以用于检查更新是否被正确安装,或者是否需要额外的更新。   在Powershell启动之前,确保你使用管理员权限启动程序,保证你有足够的权限安装所需的模块。   下面的Powershell指令将安装一个Powershell模块,用于测试Meltdown和Spectre漏洞Install-Module SpeculationControl   如果你运行上述命令后,得到一个执行错误,则可能需要调整Powershell的执行策略。运行以下命令:Set-ExecutionPolicy Bypass   现在你可以运行第二个实际检查系统的Powershelli年命令:Get-SpeculationControlSettings   Google表示,大部分的CPU都容易受到Metldown和Spectre漏洞的攻击。如果上述命令的输出结果中有很多红色的文字,说明你的系统受到威胁。           下一步是打开Windows Update并按下“检查更新”按钮,直到你收到Meltdown/Spectre补丁。根据上文所述,对于使用了“有问题”的AV程序的用户,可能需要等待几天时间。       更新之后,您需要再次运行Get-SpeculationControlSettings。有两种可能的情况。常见的情况是以下结果:    上图意味着你的系统已经修复了Meltdown漏洞,但未能完全修复Spectre程序。正如Google所说,这是意料之中的,Spectre很难利用,但也很难修补。 红色文本意味着你需要额外的芯片组固件更新。微软和谷歌表示,OEM厂商将需要为用户提供这些额外的更新,来完成Windows系统级别Spectre漏洞的完整修复。由于计算机的使用年限,某些OEM厂商可能无法提供这些固件更新,这意味着你将无法完整修复Spectre漏洞。 如果一些正常,所有的检查结果将显示为绿色文本,如下所示:完成之后,请注意将Powershell的执行策略修改为限制模式,这可以缓解Powershell执行恶意命令。Set-ExecutionPolicy Restricted
教程与文档 2 0 2304天前
admin
5366
您需要登录并回复后才可以查看该文章内容
工具 2 1 2307天前
admin
12585
原文地址:https://jingyan.baidu.com/article/046a7b3ef6b250f9c27fa9b9.html 首先,我们要先把水印模板给做出来。新建一张5厘米*5厘米的透明图层。点击“文件”->“新建。在弹出的对话框中宽度设为5厘米,高度也设为“5厘米”,背景内容设为“透明”,接着点“确定”。 2.    2  选择“横排文字工具”,把字体设为“楷体”,大小设为“30点”,文字颜色就不要紧了,反正待会要清空文字的。输文字的目的只是为了给文字描上一层灰色的边,我们要的是那层"边"。 3.    3  打完文字后,先不急着描边,先把文字放斜点。按一下“Ctrl+T”,进入“自由变换”模式,在文字的周围“按住鼠标左键就可以旋转文字”,按“回车键”退出自由变换模式。 4.    4  现在该给文字描边了,描边就是沿着字体的周围涂一层不厚也不薄的颜色,我们最后看到的水印其实就是这层边来的,一般的水印都是灰色的,好,我们就给文字描一层灰色的边。点击“添加图层样式∫X”->“描边”,进入“图层样式”对话框,大小为3像素,位置为外部,不透明度为100%,这些都按默认就行了。我们关键是要设置颜色。绝对不是要“黑色”,点击“黑色”部分进入“选取描边颜色”对话框。 5.    5  我们来到了“选取描边颜色”对话框,这里可以设置世界上会任何一种颜色,要对应的RGB码或LAB码,如果没有,那就到软件自带的“颜色库”里选取。拖动鼠标就能选到灰色。如果实在选不到,直接输入L=83,a=0,b=2也行。然后一路点“确定”就OK了。 6.    6  描完边后就成这样子了。 7.    7  接下来要把红色的字给清除了,把图层的“填充”调为0%就可以了。也许你们会误以为这样子就是最终的“水印”了。No,还差一点,这种水印太明显了,印在图片上只会让人有种“喧兵夺主”的感觉。那怎么办呢? 8.     很简单,把水印的“不透明度”调为60%就恰到好处了。这才是“终极水印”模板。 9.     我们把水印模板“自定义为图案”,随时可以为自己调用。点“编辑”->“定义图案”。在弹出的对话框中,随便填个“名称”,点“确定”,主要工作到这里基本结束了。剩下的就是如何调用的问题了。 10. 用photoshop 随便打开一张图片,点击“编辑”->“填充”,在弹出的填充对话框中点击自定图案的“下三角箭头”,在弹出的图案框中,拖动窗口的滚动条到最下面就可以看到自己制作的图案了,选定它,然后点“确定”。 11.  这就是我自制作的生日蛋糕——水印图!觉得水印还是太明显了点,你制作的时候可以把“不透明度”再调低点。 12. 如果你嫌整张图片布满水印不好看,可以把做成的“水印模板”定义为“画笔预设”,以后想在图片的哪个地方添加水印,只要选择画笔,在那个地方一点就可以了。我们来试一下,点击“编辑”->"定义画笔预设"。 13. 随便输入个名称,然后点击“确定”。那这张“水印模板”就变成“画笔工具”的一个“预设”,当我们选择“画笔工具”的时候,就可以调用了。 14. 我们选用“画笔工具”。 15. 选择“画笔预设”,选中刚才制作的“水印模板”。 16. 然后在图片上一点就是一个水印,再点一下,又一个水印,可以非常灵活。由于“画笔工具”一般是以“前景色”为画笔颜色的。所以,“前景色”的设置不同,也会导致水印的颜色不同。 17. 前景色可以配合着photoshop自带的“色板”使用,只要在“色板”上一点中,前景色就会换成相应的颜色。  
其他 1 0 2308天前
桂公网安备 45010302000666号 桂ICP备14001770-3号
感谢景安网络提供数据空间
本站CDN由七牛云提供支持
网站已接入ipv6
免责声明: 本网不承担任何由内容提供商提供的信息所引起的争议和法律责任。
如果某些内容侵犯了您的权益,请通过右侧按钮与我们联系
Your IP: 3.15.197.123 , 2024-04-29 15:43:09 , Processed in 0.60045 second(s).
Powered by HadSky 8.3.7
知道创宇云安全