github.com/go-vgo/robotgo 引入后执行报错undefined: hook.Event

一直想自己开发一个改键程序,打魔兽争霸单机的时候能使用,最近突然想试试用GO语言来实现,万能的互联网一搜,果然有,import  “github.com/go-vgo/robotgo”就可以了,带着兴奋的心情开始尝试。

go是1.20版本,

按教程
go  get  github.com/go-vgo/robotgo
直接错!因为 github.com 在国内不好使。

继续请教万能互联网

go env -w GO111MODULE=on
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/

再执行 go  get  github.com/go-vgo/robotgo ,舒服了。。。

然后测试输出版本

package main

import (
   "github.com/go-vgo/robotgo"
)

func main() {
   robotgo.keyTap(`control`, `esc`)
}

继续报错!错误信息如下:

# github.com/go-vgo/robotgo
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\hook.go:30:29: undefined: hook.Event
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\hook.go:31:14: undefined: hook.Start
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\hook.go:36:7: undefined: hook.End
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\hook.go:43:24: undefined: hook.Event
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\hook.go:44:14: undefined: hook.Start
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\hook.go:60:36: undefined: hook.Event
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\hook.go:65:69: undefined: hook.Event
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\img.go:92:40: undefined: Bitmap
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\img.go:107:38: undefined: Bitmap
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\img.go:137:20: undefined: Bitmap
 ..\pkg\mod\github.com\go-vgo\robotgo@v0.100.10\hook.go:44:14: too many errors

继续请教万能的互联网!
请教。。。。
请教。。。
请教。。
请教。
额。
不万能了,网上没有一篇文章是介绍出现这个问题的解决办法的!

所以我也不知道怎么解决!

暂时认为是没有GCC的问题,下载了 MinGW-w64 还是不行,那么不是官方包有问题(可能性不大),就是本地系统有问题。

系统问题猜想,当前用户没有权限执行hook?用管理员终端 [ 右击开始->终端(管理员) ] 重走一遍流程,发现成了报 robotgo.keyTap undefined 了。。。

再看源码,keyTap的首字母K得是大写,改一下,再执行,没报错了(会不会不是是权限问题,一直就是大小写问题啊0.0!)。但是按键命令没效果。。。

至此 hook.Event undefined 问题没有了,至于按键没效果,还得继续查是什么原因。。。

经过测试发现按键顺序不能乱放,正常顺序是 robotgo.KeyTap(`esc`,`control`),改完顺序,终于打开  开始菜单 面板了。。。

接下来是监听键盘,修改输出

fmt.Println("开启改键")

// 注册监听键盘按下事件,当按下q的时候,程序按一下小键盘7,按下d的时候,程序按一下小键盘8
robotgo.EventHook(hook.KeyDown, []string{}, func(e hook.Event) {
   if e.Keychar == 'q' {
       robotgo.KeyTap("num7")
   }
   if e.Keychar == 'd' {
       robotgo.KeyTap("num8")
   }
})
//开始监听
s := robotgo.EventStart()
// 忽略来自进程的值,防止报错
<- robotgo.EventProcess(s)

本来想实现改键的,发现robotgo只能监听消息,不能修改消息(理想情况是按下q实际系统收到的是num7,现在的情况是按下q的时候,系统 和 robotgo 都知道按下q了,然后robotgo又按了下num7),所以只能做成这种效果了,运行游戏试了下,能满足需求!!!

想要完美实现功能,还得研究windows系统接口,先到这里就打住吧。。。

一点小调整

fmt.Println("开启改键") 

// 注册监听键盘按下事件,当按下q的时候,程序按一下小键盘7,按下d的时候,程序按一下小键盘8
robotgo.EventHook(hook.KeyDown, []string{}, func(e hook.Event) {
    // 获取当前活跃窗口名称
    title := robotgo.GetTitle()
    // 如果是 War3 程序,则帮忙按键
    if(title == "Warcraft III"){
        if e.Keychar == 'q' {
            robotgo.KeyTap("num7")
        }
        if e.Keychar == 'd' {
            robotgo.KeyTap("num8")
        }
    }
})
s := robotgo.EventStart()
<- robotgo.EventProcess(s)

 

curl 为什么比 file_get_content 快

一、背景

大家做项目的时候,不免会看到前辈的代码。博主最近看到前辈有的时候请求外部接口用的是file_get_contents,有的用的是curl。稍微了解这两部分的同学都知道,curl在性能上和速度上是优于file_get_contents的,那么为什么呢,从哪里体现出来的差距呢?
二、file_get_contents和curl

1、file_get_contents概述

file_get_contents() 函数把整个文件读入一个字符串中。
手册:http://www.w3school.com.cn/php/func_filesystem_file_get_contents.asp

这里可以看出来,file_get_contents函数的最优选择是读取文件的内容。要求对方的服务器php.ini必须开启:allow_url_fopen

2、curl的概述

CURL是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。需要php.ini开启curl扩展

参考文章:http://www.cnblogs.com/manongxiaobing/p/4698990.html

从定义上来说,curl作为一个开源库,拥有众多的语法也支持众多的协议,这点能看出来curl相比于file_get_contents() 是能做更多的事情的
三、为什么curl比file_get_contents好

博主百度了网上的众多说法,总共分为下面几个方面:

1、file_get_contents() 更容易造成服务器挂掉

关于造成服务器挂掉,这部分主要涉及两个方面:

(1)直接使用file_get_contents,未设置超时处理造成nginx报错:502 Bad Gateway

这部分大家可以参考博客:http://www.cnblogs.com/aipiaoborensheng/p/5000096.html

设置超时时间即可。当然,如果是选用curl的话,设置超时时间会更加的方便,明显,一般不会因为超时而造成服务器垮掉。

(2)用file_get_contents请求效率很低,页面经常卡顿很久

这部分在网上也有个解释,说file_get_contents每次请求远程URL中的数据都会重新做DNS查询,并不对DNS信息进行缓存。而curl则可以通过设置参数的方式来缓存DNS,从而达到快速访问的目的

curl设置DNS缓存:


CURLOPT_DNS_USE_GLOBAL_CACHE 启用时会启用一个全局的DNS缓存,此项为线程安全的,并且默认启用。
CURLOPT_DNS_CACHE_TIMEOUT 设置在内存中保存DNS信息的时间,默认为120秒。


参考链接:https://www.cnblogs.com/jking10/p/6595981.html

(3)curl能做到file_get_contents做不到的事情

这部分是博主之前解决一个需求的时候发现的。当我需要把网络图片转换为二进制的图片流的时候,curl能实现,而file_get_contens就不行。

参考我之前的文章:https://blog.csdn.net/LJFPHP/article/details/81357839

2、file_get_contents速度很慢

关于速度慢的原因,一部分是DNS缓存,这确实是file_get_contents的瓶颈,另一方面就是关于header头的原因。大家都知道,file_get_contents的请求是不带头的,这样它接收完所有数据后,没有主动断开和服务器的http连接。

解决方案:


$opts = array(
‘http’=>array(
‘method’ => ‘POST’,
‘header’ => ‘Content-type:application/x-www-form-urlencoded’,
‘content’ => $postdata,
‘timeout’ => 60 * 10 // 超时时间(单位:s)
‘Connection’=>”close”
)
);
$context = stream_context_create($opts);
file_get_contents($filename, false, $context);


我们通过设置句柄的方式,定义超时时间和header头,这样就能最大化的提升file_get_contents的速度

3、file_get_contents请求HTTP时,使用的是http_fopen_wrapper,不会keeplive。而curl却可以。这样在多次请求多个链接时,curl效率会好一些。

这部分博主查询了下keeplive的相关知识,发现自己对于http请求方面还不是很熟悉。关于keeplive也是一个很大模块,博主这里就也不废话了,给大家推荐几篇不错的博客,有兴趣的可以看看:


(1)(apache)http的keeplive

https://blog.csdn.net/jackyrongvip/article/details/9217931
http://www.cnblogs.com/hixiaowei/p/9261358.html

(2)tcp的keepAlive

http://www.cnblogs.com/xiaoleiel/p/8308514.html


四、关于服务器是否支持file_get_contents的判断方法

众所周知的,file_get_contents是需要请求的服务商开启allow_url_fopen,但是很多服务商为了安全考虑都会关掉这个功能。而curl是要求php必须开启curl扩展。不过相对来说,很少有服务商不开启curl的,所以curl的运用场合会更多一些。

这里我们可以使用php自带的:function_exists方法来判断服务商是否定义的有此方法。
文档:http://php.net/manual/zh/function.function-exists.php
代码:


if(function_exists(‘file_get_contents’)) {
$file_contents = file_get_contents($url);
} else {
//这里可以执行curl方案
}


通过对比我们也能发现两个函数的优劣势。如果是读取文件或者只是去拉取数据,那么file_get_contents的效率比较高 也比较简单。如果是要进行远程连接或者高频次的访问,那么还是老老实实用curl吧。
————————————————
版权声明:本文为CSDN博主「铁柱同学」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/LJFPHP/article/details/83822628

php将长数字串变成短字符串

php将长数字串变成短字符串的方法,可用于id转化等

php将长数字串变成短字符串的方法,可用于id转化等。

$str="0abcdefghijklmnopqrstuvwxyz123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/**
  * 将数字转为短字符串
  *
  * @param int $number 数字
  * @return string 短字符串
  */
public function generate_code($number) {
	$out  = "";
	$codes = $this->str;
	while ($number > 61) {
		$m = $number % 62;
		$out = $codes[$m].$out;
		$number = ($number - $m) / 62;
	}
	return $codes[$number].$out;
}
/**
 * 将短字符串转为数字
 *
 * @param string $string短字符串
 * @return int 数字
 */
public function get_num($string){
	$codes = $this->str;
	$num = 0;
	for($i=0;$i<strlen($string);$i++){
		$n = strlen($string) - $i -1;
		$pos = strpos($codes,$string[$i]);
		$num += $pos * pow(62, $n);
	}
	return $num;
}

 

phalcon 访问IndexController 中只能访问indexAction方法,访问不了testAction

phalcon 访问IndexController 中只能访问indexAction方法,访问不了testAction
但是可以访问ArticleController里面的任意方法
看说是Apache 的rewrite问题

但是我的.htaccess文件都是按照文档里面的。

两个.htaccess

第一个

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule  ^$ public/    [L]
<span">RewriteRule  ((?s).*) public/$1 [L] 
</IfModule>

public目录下面的.htaccess中

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L] 
</IfModule>

访问路由 localhost/index/test访问不到,但是localhost/index.php?_url=/index/test可以访问得到

解决方法:

直接打印 $_request,发现当路径为 localhost/index/test 的时候,没有_url参数,判断是url重新没成功。将 RewriteCond %{REQUEST_FILENAME} !-f 这行去掉,发现_url 的值是 index.php/test

也就是说apache没有将index/test 看成一个整体,分开请求了,先请求index再请求test,当index不存在时,直接去找index.php,index.html,此时index匹配成功重写取消,而index下的test没有匹配成功,重写后就成了index.php/test了。那么apache为什么不是把index/test看成一个整体,而是分开去处理呢?

怀疑是因为httpd.conf中打开了允许列出目录的功能 mod_autoindex;并设置了Options Indexes允许目录浏览,受目录浏览影响导致重写问题,

取消掉Options 的其他参数,仅保留FollowSymLinks参数,重启apache后,index/test 可以正常访问了

难道真是目录浏览功能的问题?

Options +Indexes +Includes +FollowSymLinks +MultiViews

配置中一共有四个参数,挨个试,最后发现是受MultiViews参数影响。。。但是具体为什么就不清楚了,

ps:出现该问题的工具是wampserver 3.0.6 64bit 版本,32bit版本的没出现该问题,老版的apache也没出过现该问题,猜测可能是apache版本升级进行了什么调整导致的,具体原因再论。

2018-11-28 更新
今天看到一篇文章,标题为: apache的MultiViews的问题

文章来源:https://blog.csdn.net/u014359108/article/details/70859651

该博文介绍了:

MultiViews的作用是当访问到目录中不存在的对象时,
如访问”http://localhost/test/target”,
则apache会寻找该目录下的所有target.*文件.
如果test目录下存在target.jpg文件,
则会把这个文件返回给客户,
而不是返回出错信息.
再分析一下我们现在面对的实例.由于MultiViews的特性,
当访问“http://servername/Index/index”时.
由于根目录下存在index.php文件
所以上面的访问会变成这样:
“http://servername/Index.php/index”

到这里,就清楚为什么httpd.conf中有MultiViews 配置是

Options +FollowSymLinks +MultiViews

phalcon 访问indexController 的方法是就只能访问indexAction()了

dede 添加addfields属性后,自定义字段还是出不来

dede 添加addfields属性后,自定义字段还是出不来

如下列内容,写好后,发现自定义的mytitle字段没法显示,

{dede:arclist addfields=’mytitle’ row=’8′ }
[field:mytitle/]<br />
{/dede:arclist}

别人的东西用起来就是麻烦,网上查还查不到详细介绍,

但是通过详细观察发现,arclist 用到 addfields 属性时,都伴有 channelid 属性,难道是缺少了这个属性导致的

{dede:arclist addfields=’mytitle’ row=’8′ channelid=’3′ }
[field:mytitle/]<br />
{/dede:arclist}

加上后,自定义的 mytitle 字段可正常显示了

wordpress更新提示“另一更新正在进行”

在后台准备选择WordPress自动升级的时候看到有”另一更新正在进行”错误提示,无法执行升级到最新版本的问题。通过搜索看到也有网友遇到这个问题,可能是因为上一次升级过程中导致占用库表,然后被锁定的关系无法继续。

第一、出现的错误问题

完整解决升级WordPress程序提示"另一更新正在进行"问题

应该是数据库表中有表被锁定导致无法继续。

第二、解决问题

1、登入数据库客户端,打开wp_options数据表,然后找到core_updater.lock字段。

SELECT * FROM blog_options WHERE option_name LIKE ‘%core_updater.lock%’

 

2、找到这个字段,然后删除。

最后,我们再去执行升级WordPress就没有这个”另一更新正在进行”问题错误提示,问题解决了。

执行 rm -rf /bin 命令后

不小心删除了/bin目录,对于我们这种对系统认识不太高的人来说,的确是受到了灾难性的打击,但是静下心来好好搜索分析,还是能找到解决办法的,跨过了一个坎,就是一次成长,亲们,发现php的强大了吗^_^!

由于服务器被挖矿程序黑了,cpu占到100%,在删除相关问题文件的时候,不小心执行了 rm -rf /bin 命令,然后再删除另一个恶意文件时,发现rm命令不能用了,查询一下,发现ls和vi这些个基本命令全都不可用了,这下发现自己闯大祸了。线上服务器出问题从来没有小问题。

什么都不敢动了,赶紧网上查解决办法,网上大体上是给出了两个方案:一个是去机房使用系统光盘恢复bin目录;一个是从相同系统中拷贝bin目录下的文件到当前目录。简单了解了下,如果删除后取消了远程连接,也没办法再登录了,就只能用第一个方法了。还好,我保留着连接没有断,另外有一个相同系统的正常的服务器的bin目录可供使用,所以决定用第二个方案。

然而,问题又来了,bin被删除后,基本上系统什么命令都没办法执行了,cp,scp等等所有能用的命令都不可用了。。。

正在陷入极度恐慌之时,搜索到一篇文章,给了我一个思路,文章地址:http://www.cnblogs.com/hark0623/p/5886091.html,就是将文件放到web服务器上,然后通过wget将文件拉倒当前服务器来。接下来将被删除bin目录的服务器称为A,同系统正常服务器称为B;

按照这个思路,我将B服务器上的bin目录copy了一份到B服务器的web目录,浏览器测试可以将文件下载下来,接下来考虑怎样在A服务器上获取文件。原本文章里面说的使用wget的功能,经测试发现命令不可用,就是说wget也是在bin目录里的命令。那就再换思路,除了bin目录里的命令,还有哪些是可以远程获取文件内容的。

由于A、B两台服务器用的都是php,我就考虑,能不能用php的函数实现从B服务器上复制文件到A服务器上来的可能性。

php执行脚本的路子已经很熟悉了,但是当前情况是,A服务器上已经没办法进行vi等类似的编辑操作,也没法进行git等版本控制器的操作了,那么php有没有类似的命令行操作呢?然后继续网上搜索信息,发现php是可以直接执行php脚本的,参考文章地址:http://www.linuxdiyf.com/linux/13076.html,文章里提供了一个方法:

/usr/local/php/bin/php -r 'phpinfo();'

经过测试,使用下面的命令:

/usr/local/php/bin/php -r '$content=file_get_contents("http://abc.def.com/testbin/ls");file_put_contents("ls",$content);'

顺利的将B服务器上的文件拷贝到了A服务器上来,测试是否可用

./ls

提示权限不足,跟这篇文章给的结果一样:http://www.cnblogs.com/hark0623/p/5886091.html,采用文章里的方法:perl -e “chmod 0777, ‘mkdir'”,perl命令依然不能用,那就继续php解决:

/usr/local/php/bin/php -r 'chmod("ls",0777);'

再次测试 ./ls 发现可用了,按照这个思路,重点拿到了cp和rz文件,通过cp将rz文件copy到 /bin 目录下,然后将剩下的文件全部通过rz上传到A服务器的/bin目录,chmod修改权限后,基本命令都恢复可用了,远程登录也OK了,至此问题解决

php+jquery玩转json数据

web开发,怎样用json数据才能用的爽?

由于json格式的数据在使用上的优势很明显,现在做项目时大多使用json格式进行数据传输,如果使用 php + jquery + ajax ,那使用json数据让码农怎一个爽字了得。。。

但是需要注意的是,php有个函数是将数据转换成json串,不说你们也知道了,就是json_encode()函数,而用这个函数后直接将数据echo,jquery还是不认数据是json数据的,只认为是普通字符串。这事,处理返回结果就让人不爽,复制下面的代码,放到php里面,返回的数据,js可以直接当对象用了,大功告成。。。

header(“Content-type:text/json”);

header头内容不做多余介绍,只要大家用的爽就行,想了解可以自己学去!!!

dedecms安装后common.inc.php 文件权限一直是777的解决方法

dede common.inc.php这个文件总是777权限的解决方案

今天无忧主机小编给无忧主机客户在免备案空间安装好dedecms之后,过了没有多久客户找过说是后台提示有安全的问题,于是进去查看了一下common.inc.php这个文件是777权限,按照官方的要求必须是644权限,所以去修改之后刷新了一下又变回了777权限。那么经过精心的去发现以及查看资料终于得到了解决方案。
于是乎无忧主机小编猜测是有文件该文件有写入权限,把权限改了444后问题依然。如何解决?通过测试在后台的点击其它页面文件权限不会改变,那就是一登陆主页产生的写入权限。
接下来无忧主机小编就给大家说说如何解决:
找到目录下的dede/templets下的index_body.htm,全部删除测试看看是不是不会有这样的问题了。后来发现有一个js文件不加载就可以了。
下接将文件的这个js 去掉 就可以了

1 <script language="javascript" src="js/drag.js"></script>

其它不会有这问题的,可将这个common.inc.php改为444,后台就不会再有提示,并且不会自动更改了,如图1所示:

220 dedecms安装后common.inc.php 文件权限一直是777的解决方法

在刷新下,发现没有提示安全问题了,如图2所示:

315 dedecms安装后common.inc.php 文件权限一直是777的解决方法

我们在进入空间,看到文件common.inc.php的权限也不变了。那么这个问题也得到了解决。
温馨提示:该技术解决方案的是由无忧主机客服为我们空间客户处理该问题时提供的处理方法,确保在无忧主机能完美实现,因服务较多,客服繁忙,其他主机我们没有过多精力进行大范围测试,不能确保所有虚拟主机都能完美处理,请您理解!

文章来源:无忧主机http://www.51php.com/dedecms/23260.html

php 设定cookie名会自动将点”.”转为下划线”_”

php cookie中不能使用点号(句号),实际上不是很严格,应该说可以使用点号的cookie名,但会被转换,你命名一个cookie:

$_COOKIE[‘my.name’] = 1;

实际上你不能通过’my.name’在cookie中查找到这个值,只能是’my_name’:

echo $_COOKIE[‘my_name’];

php已经自动帮你进行了转化,句点转为了下划线。

php为什么要这样做呢?这是因为$_GET/$_POST/$_SERVER/$_COOKIE。。。这些全局函数的值,在之前的许多版本中是可以通过register_globals参数在本地中直接访问这些值的,比如开启register_globals = on后,访问$my_name直接取值为1。如果是$my.name的话,则不符合php变量命名原则,这不单是句号(.)的问题。

因此,$_COOKIE的命名已经符合php命名标准。

另外开启register_globals是一个很糟糕的决定,因为它可能会覆盖脚本中原来的值,比如:

// other code
if ($a)
$uc_is_login = true;
// …

用户只需要发送一个url?a=1的http请求就可以默认已经登陆。这是个很危险的做法,应该把它关闭。实际上php6已经去除了这个选项。

文章来源:http://www.jb51.net/article/56483.htm