├── .buildpath ├── .project ├── .pydevproject ├── .settings └── org.eclipse.core.resources.prefs ├── Node └── PlayWeb │ ├── __init__.py │ ├── __init__.pyc │ ├── crawler.py │ ├── crawler.pyc │ ├── g.py │ ├── g.pyc │ ├── http.py │ ├── http.pyc │ ├── lfi.py │ ├── lfi.pyc │ ├── playweb.py │ ├── scanner.py │ ├── scanner.pyc │ ├── sqli.py │ ├── sqli.pyc │ ├── test.py │ ├── test.pyc │ ├── util.py │ ├── util.pyc │ ├── x.py │ ├── xss.py │ └── xss.pyc ├── README.md ├── Static ├── css │ ├── bootstrap-responsive.css │ ├── bootstrap-responsive.min.css │ ├── bootstrap-wizard.css │ ├── bootstrap.css │ ├── bootstrap.min.css │ ├── green.png │ ├── green@2x.png │ └── style.css ├── img │ ├── 8642.png │ ├── android.png │ ├── apple.png │ ├── flattr-badge-large.png │ ├── gb_tip_layer.png │ ├── gb_tip_layer_ie6.png │ ├── gb_tip_loading.gif │ ├── glyphicons-halflings-white.png │ ├── glyphicons-halflings.png │ ├── linux.png │ ├── loading.gif │ └── windows.png └── js │ ├── bootstrap-wizard.js │ ├── bootstrap.js │ ├── bootstrap.min.js │ ├── highcharts.js │ ├── icheck.min.js │ ├── index.js │ ├── jquery.js │ ├── playweb.js │ └── uauc.js ├── ThinkPHP ├── Common │ ├── common.php │ ├── functions.php │ └── runtime.php ├── Conf │ ├── alias.php │ ├── convention.php │ ├── debug.php │ └── tags.php ├── Extend │ └── README.txt ├── LICENSE.txt ├── Lang │ ├── en-us.php │ └── zh-cn.php ├── Lib │ ├── Behavior │ │ ├── CheckRouteBehavior.class.php │ │ ├── ContentReplaceBehavior.class.php │ │ ├── ParseTemplateBehavior.class.php │ │ ├── ReadHtmlCacheBehavior.class.php │ │ ├── ShowPageTraceBehavior.class.php │ │ ├── ShowRuntimeBehavior.class.php │ │ ├── TokenBuildBehavior.class.php │ │ └── WriteHtmlCacheBehavior.class.php │ ├── Core │ │ ├── Action.class.php │ │ ├── App.class.php │ │ ├── Behavior.class.php │ │ ├── Cache.class.php │ │ ├── Db.class.php │ │ ├── Dispatcher.class.php │ │ ├── Log.class.php │ │ ├── Model.class.php │ │ ├── Think.class.php │ │ ├── ThinkException.class.php │ │ ├── View.class.php │ │ └── Widget.class.php │ ├── Driver │ │ ├── Cache │ │ │ └── CacheFile.class.php │ │ ├── Db │ │ │ ├── DbMysql.class.php │ │ │ └── DbMysqli.class.php │ │ └── TagLib │ │ │ └── TagLibCx.class.php │ └── Template │ │ ├── TagLib.class.php │ │ └── ThinkTemplate.class.php ├── README.txt ├── ThinkPHP.php ├── Tpl │ ├── default_index.tpl │ ├── dispatch_jump.tpl │ ├── page_trace.tpl │ └── think_exception.tpl └── logo.png ├── favicon.ico ├── index.php ├── playweb.sql └── playweb ├── Common ├── common.php └── functions.php ├── Conf └── config.php ├── Lib ├── Action │ ├── CommonAction.class.php │ ├── IndexAction.class.php │ ├── NodeAction.class.php │ ├── ProjectAction.class.php │ ├── ReportAction.class.php │ └── UserAction.class.php └── Model │ ├── NodeModel.class.php │ └── UserModel.class.php ├── Runtime └── Cache │ ├── 2d57c07f14e7f6e0bbf4108f98365878.php │ ├── 3115e2bee587dd2d65fbcebf532f0bf5.php │ ├── 3ef5e2f17b29f37d0c954b34f6e3fa90.php │ ├── 477cb8eed6d581df4cc21aa850723f4a.php │ ├── 9885ecc411f90bec36756701bd64bb4a.php │ └── a8f553bbee87836198ce5a1333d1f6c2.php └── Tpl ├── Index └── index.html ├── Public ├── base.html └── dialog.html ├── Report └── view.html └── User ├── Login.html └── Reg.html /.buildpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | playweb 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.wst.validation.validationbuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.dltk.core.scriptbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.php.core.PHPNature 26 | org.python.pydev.pythonNature 27 | 28 | 29 | -------------------------------------------------------------------------------- /.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | python 2.7 4 | Default 5 | 6 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | #Sun Jun 01 16:32:48 CST 2014 2 | eclipse.preferences.version=1 3 | encoding//Node/PlayWeb/playweb.py=utf-8 4 | encoding//Node/PlayWeb/scanner.py=utf-8 5 | encoding//Node/PlayWeb/sqli.py=utf-8 6 | encoding//Node/PlayWeb/test.py=utf-8 7 | encoding//Node/PlayWeb/util.py=utf-8 8 | encoding//PlayWeb/Tpl/Report/view.html=UTF-8 9 | encoding/=UTF-8 10 | -------------------------------------------------------------------------------- /Node/PlayWeb/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/__init__.py -------------------------------------------------------------------------------- /Node/PlayWeb/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/__init__.pyc -------------------------------------------------------------------------------- /Node/PlayWeb/crawler.py: -------------------------------------------------------------------------------- 1 | """ 2 | * @id PlayWeb-2014-3-28 3 | * @desc 爬虫 4 | * @author Yaseng WwW.Yaseng.Me [Yaseng@UAUC.NET] 5 | * @project github.com/yaseng/playweb 6 | """ 7 | import urllib, urllib2, urlparse, re, os, time 8 | from HTMLParser import HTMLParser, HTMLParseError 9 | from http import Url, GetRequest, PostRequest 10 | import g 11 | 12 | class Crawler(HTMLParser): 13 | def __init__(self, root): 14 | HTMLParser.__init__(self) 15 | self.scheme = root.scheme 16 | self.domain = root.netloc 17 | self.root = root 18 | self.requests = [] 19 | self.parsed = [] 20 | self.form = None 21 | self.current = None 22 | 23 | def parse(self, request): 24 | if g.O['file-ext'] != None: 25 | (root, ext) = os.path.splitext(request.url.path) 26 | if ext[1:] not in g.O['file-ext'] and ext != '': 27 | self.parsed.append(request) 28 | return 29 | 30 | if g.O['depth'] != None: 31 | if len(request.url.path.split('/')) + 1 > g.O['depth']: 32 | 33 | self.parsed.append(request) 34 | return 35 | try: 36 | response = request.fetch() 37 | response = re.sub("href\s*=\s*([^\"'\s>]+)" , r'href="\1"', response) 38 | response = re.sub("src\s*=\s*([^\"'\s>]+)" , r'src="\1"', response) 39 | response = re.sub("action\s*=\s*([^\"'\s>]+)" , r'action="\1"', response) 40 | response = re.sub("method\s*=\s*([^\"'\s>]+)" , r'method="\1"', response) 41 | response = re.sub("name\s*=\s*([^\"'\s>]+)" , r'name="\1"', response) 42 | response = re.sub("value\s*=\s*([^\"'\s>]+)" , r'value="\1"', response) 43 | self.current = request.url 44 | self.feed(response) 45 | self.close() 46 | 47 | except Exception as e: 48 | #print e 49 | pass 50 | 51 | finally: 52 | self.parsed.append(request) 53 | if request.redirect != None: 54 | url = Url(request.redirect, default_netloc=self.domain, default_path=self.root.path) 55 | self.parsed.append(GetRequest(url)) 56 | 57 | for req in self.requests: 58 | if req not in self.parsed: 59 | self.parse(req) 60 | 61 | 62 | 63 | 64 | 65 | def __get_attr(self, name, attrs, default=''): 66 | for a in attrs: 67 | aname = a[0].lower() 68 | if aname == name: 69 | return a[1] 70 | return default 71 | 72 | def __auto_input_form(self,name): 73 | datas = {"user*":"admin", "pass*":"admin", "email.*":"heisenberg@gmail.com","tel*":"139785452465"} 74 | for key in datas: 75 | if re.search(key, name): 76 | return datas[key] 77 | 78 | 79 | 80 | 81 | def __sameDomain(self, domain): 82 | return re.match(".*\.?%s" % re.escape(self.domain), domain) or re.match(".*\.?%s" % re.escape(domain), self.domain) 83 | 84 | def handle_starttag(self, tag, attrs): 85 | tag = tag.lower() 86 | if tag == 'a': 87 | href = self.__get_attr('href', attrs) 88 | url = Url(href, default_netloc=self.domain, default_path=self.current.path) 89 | if self.__sameDomain(url.netloc) and url.scheme == self.scheme: 90 | req = GetRequest(url) 91 | if req not in self.requests: 92 | self.requests.append(req) 93 | elif tag == 'frame' or tag == 'iframe': 94 | src = self.__get_attr('src', attrs) 95 | url = Url(src, default_netloc=self.domain, default_path=self.current.path) 96 | if self.__sameDomain(url.netloc) and url.scheme == self.scheme: 97 | req = GetRequest(url) 98 | if req not in self.requests: 99 | self.requests.append(req) 100 | elif tag == 'form': 101 | self.form = {} 102 | self.form['data'] = {} 103 | self.form['action'] = self.__get_attr('action', attrs, self.current.path) 104 | self.form['method'] = self.__get_attr('method', attrs, 'get').lower() 105 | elif self.form != None: 106 | if tag == 'input': 107 | name = self.__get_attr('name', attrs) 108 | value = self.__get_attr('value', attrs) 109 | if value == "" : 110 | value=self.__auto_input_form(name) 111 | self.form['data'][name] = value 112 | elif tag == 'select': 113 | #name = self.__get_attr('name', attrs) auto select!!! 114 | #print self.__get_attr('value', attrs) 115 | self.form['data'][self.__get_attr('name', attrs)] = '' 116 | 117 | def handle_endtag(self, tag): 118 | tag = tag.lower() 119 | if tag == 'form' and self.form != None: 120 | if self.form['method'] == 'get': 121 | link = self.form['action'] + "?" + urlencode(self.form['data']) 122 | url = Url(link, default_netloc=self.domain) 123 | if self.__sameDomain(url.netloc) and url.scheme == self.scheme: 124 | req = GetRequest(url) 125 | if req not in self.requests: 126 | self.requests.append(req) 127 | elif self.form['method'] == 'post': 128 | link = self.form['action'] 129 | url = Url(link, default_netloc=self.domain, default_path=self.current.path) 130 | if self.__sameDomain(url.netloc) and url.scheme == self.scheme: 131 | req = PostRequest(url) 132 | for name, value in self.form['data'].items(): 133 | req.addField(name, value) 134 | if req not in self.requests: 135 | self.requests.append(req) 136 | 137 | self.form = None -------------------------------------------------------------------------------- /Node/PlayWeb/crawler.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/crawler.pyc -------------------------------------------------------------------------------- /Node/PlayWeb/g.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | O={} 5 | 6 | def config(option): 7 | global O 8 | O=option 9 | 10 | def set(key,value): 11 | global O 12 | O[key]=value 13 | 14 | 15 | -------------------------------------------------------------------------------- /Node/PlayWeb/g.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/g.pyc -------------------------------------------------------------------------------- /Node/PlayWeb/http.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # This file is part of Altair web vulnerability scanner. 3 | # 4 | # Copyright(c) 2010-2011 Simone Margaritelli 5 | # evilsocket@gmail.com 6 | # http://www.evilsocket.net 7 | # http://www.backbox.org 8 | # 9 | # This file may be licensed under the terms of of the 10 | # GNU General Public License Version 2 (the ``GPL''). 11 | # 12 | # Software distributed under the License is distributed 13 | # on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either 14 | # express or implied. See the GPL for the specific language 15 | # governing rights and limitations. 16 | # 17 | # You should have received a copy of the GPL along with this 18 | # program. If not, go to http://www.gnu.org/licenses/gpl.html 19 | # or write to the Free Software Foundation, Inc., 20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 | from urllib import quote, unquote, urlencode 22 | import urlparse 23 | import urllib2 24 | import unicodedata 25 | import re 26 | import os 27 | 28 | class Url: 29 | def __init__( self, url, default_netloc = '', default_scheme = 'http', default_path = '/' ): 30 | p = urlparse.urlparse(url) 31 | self.scheme = p.scheme if p.scheme != '' else default_scheme 32 | self.netloc = p.netloc if p.netloc != '' else default_netloc 33 | self.path = p.path if p.path != '' else default_path 34 | self.params = {} 35 | self.query = p.query 36 | 37 | # decode 38 | if isinstance( self.path, unicode ): 39 | self.path = unicodedata.normalize( 'NFKD', self.path ).encode('ascii','ignore') 40 | 41 | # remove default net location from path 42 | if self.netloc in self.path: 43 | self.path = self.path.replace( self.netloc, '' ) 44 | 45 | # fix path 46 | if self.path[0] != '/': 47 | if re.match( '^.+\.[^\.]+$', self.path ): 48 | self.path = os.path.split(default_path)[0] + "/" + self.path 49 | else: 50 | self.path = default_path + "/" + self.path 51 | 52 | # fix relative path 53 | if '.' in self.path: 54 | tree = filter( str.strip, self.path.split('/') ) 55 | path = [] 56 | for item in tree: 57 | if item == '.': 58 | pass 59 | elif item == '..': 60 | if len(path): path.pop() 61 | else: 62 | path.append(item) 63 | 64 | self.path = "/%s" % "/".join(path) 65 | 66 | # split and parse params 67 | if self.query != '': 68 | self.params = {} 69 | args = urlparse.parse_qs( unquote(self.query) ) 70 | for k,v in args.items(): 71 | self.params[k] = v[0] 72 | 73 | def copy( self ): 74 | return Url( self.get(), self.netloc, self.scheme, self.path ) 75 | 76 | def __composeQuery( self ): 77 | kvs = [] 78 | for k, v in self.params.items(): 79 | kvs.append( "%s=%s" % ( quote( k ), quote( v ) ) ) 80 | self.query = "&".join(kvs) 81 | 82 | def __ne__ ( self, url ): 83 | return not self.__eq__( url ) 84 | 85 | def __eq__ ( self, url ): 86 | if self.scheme != url.scheme: 87 | return False 88 | elif self.netloc != url.netloc: 89 | return False 90 | elif self.path != url.path: 91 | return False 92 | elif self.params.keys().sort() != url.params.keys().sort(): 93 | return False 94 | else: 95 | return True 96 | 97 | def get( self ): 98 | self.__composeQuery() 99 | return "%s://%s%s%s%s" % ( self.scheme, self.netloc, self.path, '?' if self.query != '' else '', self.query ) 100 | 101 | def __str__( self ): 102 | return "URL ( scheme = %s, netloc = %s, path = %s, params = %s, query = %s)" % (self.scheme,self.netloc,self.path,self.params,self.query) 103 | 104 | class RedirectHandler(urllib2.HTTPRedirectHandler): 105 | def redirect_request(self, req, fp, code, msg, headers, newurl): 106 | m = req.get_method() 107 | if (code in (301, 302, 303, 307) and m in ("GET", "HEAD") or code in (301, 302, 303) and m == "POST"): 108 | newurl = newurl.replace(' ', '%20') 109 | newheaders = dict((k,v) for k,v in req.headers.items() 110 | if k.lower() not in ("content-length", "content-type") 111 | ) 112 | 113 | return urllib2.Request( newurl, 114 | headers = newheaders, 115 | origin_req_host=req.get_origin_req_host(), 116 | unverifiable=True) 117 | else: 118 | raise HTTPError(req.get_full_url(), code, msg, headers, fp) 119 | 120 | class Request: 121 | def __init__( self, url ): 122 | self.type = 0 123 | self.url = url.copy() 124 | self.dyn_url = url.copy() 125 | self.redirect = None 126 | self.headers = {} 127 | self.fields = {} 128 | self.dyn_fields = {} 129 | 130 | def copy( self ): 131 | req = Request( self.url ) 132 | req.type = self.type 133 | req.headers = self.headers.copy() 134 | req.fields = self.fields.copy() 135 | req.dyn_fields = self.dyn_fields.copy() 136 | return req 137 | 138 | def setProxy( self, address, port ): 139 | proxy = urllib2.ProxyHandler( {"http" : "http://%s:%d" % (address,port) } ) 140 | opener = urllib2.build_opener( proxy ) 141 | urllib2.install_opener(opener) 142 | 143 | def setParam( self, name, value ): 144 | self.dyn_url.params[name] = value 145 | 146 | def getParam(self,name): 147 | return self.url.params[name] 148 | 149 | def addField( self, name, value ): 150 | self.fields[name] = value 151 | self.dyn_fields[name] = value 152 | 153 | def setField( self, name, value ): 154 | self.dyn_fields[name] = value 155 | 156 | def getField(self,name): 157 | return self.fields[name] 158 | 159 | def setHeader( self, name, value ): 160 | self.headers[name] = value 161 | 162 | def reset( self ): 163 | self.dyn_url = self.url.copy() 164 | self.dyn_fields = self.fields.copy() 165 | 166 | def __ne__ ( self, req ): 167 | return not self.__eq__( req ) 168 | 169 | def __eq__( self, req ): 170 | if self.type != req.type: 171 | return False 172 | if self.url != req.url: 173 | return False 174 | elif self.fields.keys().sort() != req.fields.keys().sort(): 175 | return False 176 | else: 177 | return True 178 | 179 | def fetch( self ): 180 | req = urllib2.Request( self.dyn_url.get(), urlencode(self.dyn_fields) if self.dyn_fields != {} else None, self.headers ) 181 | opener = urllib2.build_opener( RedirectHandler() ) 182 | res = opener.open(req) 183 | resp = res.read() 184 | 185 | if res.url != ("%s://%s%s" % ( self.url.scheme, self.url.netloc, self.url.path )): 186 | self.redirect = res.url 187 | else: 188 | self.redirect = None 189 | 190 | return resp 191 | 192 | 193 | class GetRequest(Request): 194 | def __init__( self, url ): 195 | Request.__init__( self, url ) 196 | self.type = 1 197 | 198 | def __str__( self ): 199 | return "GET : %s" % self.dyn_url 200 | 201 | class PostRequest(Request): 202 | def __init__( self, url ): 203 | Request.__init__( self, url ) 204 | self.type = 2 205 | 206 | def __str__( self ): 207 | return "POST %s : %s" % ( self.dyn_fields, self.dyn_url ) 208 | -------------------------------------------------------------------------------- /Node/PlayWeb/http.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/http.pyc -------------------------------------------------------------------------------- /Node/PlayWeb/lfi.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | 3 | 4 | 5 | LFI_POCS={ '/etc/passwd' : '/usr/sbin:', 6 | '/etc/ssh/sshd_config' : 'X11Forwarding', 7 | '/etc/hosts' : 'localhost', 8 | } 9 | 10 | LFI_DEPTH=6 11 | 12 | def exploit(url): 13 | if not url.params: 14 | return 15 | -------------------------------------------------------------------------------- /Node/PlayWeb/lfi.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/lfi.pyc -------------------------------------------------------------------------------- /Node/PlayWeb/playweb.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | import os, time,itertools,sys,Queue, threading,imp 3 | from crawler import * 4 | from http import Url 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | 8 | 9 | 10 | class Worker(threading.Thread): 11 | def __init__(self): 12 | threading.Thread.__init__(self) 13 | def run(self): 14 | while 1: 15 | if task_queue.empty() == True: 16 | break 17 | task=task_queue.get() 18 | module[task['module']].exploit(task['request']) 19 | 20 | if __name__ == '__main__': 21 | target = Url("http://w") 22 | o = {"depth":5, "ext":['cgi', 'cfm', 'asp', 'aspx', 'jsp', 'php', 'htm', 'html', 'do'], } 23 | thread=10 24 | #module_list=["sqli","xss","lfi","ftp_login","ssh_login"] 25 | module_list=["sqli","xss"] 26 | module={} 27 | ya = Crawler(target, o) 28 | ya.parse(GetRequest(target)) 29 | task_queue = Queue.Queue() 30 | for item in module_list: 31 | module[item]= __import__(item) 32 | for request in ya.requests: 33 | task_queue.put({"module":item,"request":request}) 34 | 35 | for t in range(3): 36 | Worker().start() 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Node/PlayWeb/scanner.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/scanner.pyc -------------------------------------------------------------------------------- /Node/PlayWeb/sqli.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | """ 3 | * @id PlayWeb-2014-3-28 4 | * @desc fuzzing-sqli module 5 | * @author Yaseng WwW.Yaseng.Me [Yaseng@UAUC.NET] 6 | * @project github.com/yaseng/playweb 7 | """ 8 | import itertools, re, random, util 9 | from http import Url, GetRequest, PostRequest 10 | 11 | SQL_PREFIXES = (" ", ") ", "' ", "') ", "\"") 12 | SQL_SUFFIXES = ("", "-- ", "#", "%%00", "%%16") 13 | SQL_POCS = ("'", '(', ')', '"') 14 | SQL_BOOLEAN_TESTS = "And 1=1" 15 | 16 | SQLI_ERROR_SINGS = { 17 | "MySQL": (u"SQL syntax.*MySQL", u"Warning.*mysql_.*", u"valid MySQL result", u"MySqlClient\."), 18 | "PostgreSQL": (u"PostgreSQL.*ERROu", u"Warning.*\Wpg_.*", u"valid PostgreSQL result", u"Npgsql\."), 19 | "Microsoft SQL Server": (u"Driver.* SQL[\-\_\ ]*Serveu", u"OLE DB.* SQL Serveu", u"(\W|\A)SQL Server.*Driveu", u"Warning.*mssql_.*", u"(\W|\A)SQL Server.*[0-9a-fA-F]{8}", u"(?s)Exception.*\WSystem\.Data\.SqlClient\.", u"(?s)Exception.*\WRoadhouse\.Cms\."), 20 | "Microsoft Access": (u"Microsoft Access Driveu", u"JET Database Engine", u"Access Database Engine"), 21 | "Oracle": (u"ORA-[0-9][0-9][0-9][0-9]", u"Oracle errou", u"Oracle.*Driveu", u"Warning.*\Woci_.*", u"Warning.*\Wora_.*") 22 | } 23 | 24 | 25 | def exploit(request): 26 | if not request.url.params: 27 | return 28 | for param in request.url.params: # only get 29 | for poc in SQL_POCS: 30 | injectable = False 31 | req_tmp = request.copy() 32 | req_tmp.__class__ = GetRequest 33 | req_tmp.setParam(param, req_tmp.getParam(param) + poc) 34 | for (dbms, regex) in ((dbms, regex) for dbms in SQLI_ERROR_SINGS for regex in SQLI_ERROR_SINGS[dbms]): 35 | if re.search(regex, req_tmp.fetch(), re.I): 36 | # print "%s" % req_tmp 37 | util.report({"type":"sqli", "content":util.json_encode({"sqli_type":"%s Error Based" % dbms, "param":param, "detail":"%s" % req_tmp})}) 38 | return 39 | for prefix, suffix in itertools.product(SQL_PREFIXES, SQL_SUFFIXES): 40 | poc1 = "%s AND 1=1 %s" % (prefix, suffix) 41 | poc2 = "%s AND 1=2 %s" % (prefix, suffix) 42 | req_tmp1 = request.copy() 43 | req_tmp1.__class__ = GetRequest 44 | req_tmp1.setParam(param, req_tmp1.getParam(param) + poc1) 45 | req_tmp2 = request.copy() 46 | req_tmp2.__class__ = GetRequest 47 | req_tmp2.setParam(param, req_tmp2.getParam(param) + poc2) 48 | if (len(req_tmp1.fetch()) != len(req_tmp2.fetch())): 49 | util.report({"type":"sqli", "content":util.json_encode({"sqli_type":"UNION query", "param":param, "detail":"%s" % req_tmp})}) 50 | # print "UNION SQLI:param %s %s" % (param,req_tmp2) 51 | return 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Node/PlayWeb/sqli.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/sqli.pyc -------------------------------------------------------------------------------- /Node/PlayWeb/test.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | """ 3 | * @id PlayWeb-2014-3-28 4 | * @desc 扫描节点入口 5 | * @author Yaseng WwW.Yaseng.Me [Yaseng@UAUC.NET] 6 | * @project github.com/yaseng/playweb 7 | """ 8 | import os, time, itertools, sys, Queue, threading, itertools 9 | from crawler import * 10 | from scanner import * 11 | import util, g 12 | reload(sys) 13 | sys.setdefaultencoding('utf8') 14 | 15 | class WorkManager(object): 16 | 17 | def __init__(self, queue, thread_num=2): 18 | self.work_queue = queue 19 | self.threads = [] 20 | self.__init_thread_pool(thread_num) 21 | 22 | 23 | 24 | def __init_thread_pool(self, thread_num): 25 | for i in range(thread_num): 26 | self.threads.append(Work(self.work_queue)) 27 | 28 | 29 | 30 | 31 | def add_job(self, func, *args): 32 | self.work_queue.put((func, list(args))) 33 | 34 | 35 | 36 | def check_queue(self): 37 | return self.work_queue.qsize() 38 | 39 | 40 | 41 | def wait_allcomplete(self): 42 | for item in self.threads: 43 | if item.isAlive(): 44 | item.join() 45 | 46 | class Work(threading.Thread): 47 | def __init__(self, work_queue): 48 | threading.Thread.__init__(self) 49 | self.work_queue = work_queue 50 | self.start() 51 | 52 | def run(self): 53 | while True: 54 | try: 55 | task = self.work_queue.get(block=False) 56 | print type(task) 57 | #task = task_queue.get() 58 | module[task['module']].exploit(task['request']) 59 | self.work_queue.task_done() 60 | except Exception, e: 61 | #print str(e) 62 | break 63 | 64 | 65 | 66 | if __name__ == '__main__': 67 | 68 | 69 | O = {} 70 | NODE_KEY = "a88b92531ba974f68bc1fd5938fc77" 71 | NODE_DEBUG = 0 72 | SERVER = "http://w/uauc/playweb/" 73 | util.msg("PlayWeb Node 1.0") 74 | util.msg("Server:%s Key:%s Debug:%d" % (SERVER, NODE_KEY, NODE_DEBUG)) 75 | util.msg("Listening server project...") 76 | while 1: 77 | r = util.http_get(SERVER + "/index.php?m=node&a=get_task") 78 | if r['data'] != " " : 79 | O = eval(util.decode_str(r['data'], NODE_KEY)) 80 | break 81 | time.sleep(1) 82 | O['debug'] = NODE_DEBUG 83 | util.msg("[Project] Target:%s Time:%s Module:%s Thread:%s" % (O['target'], util.date(O['start_time']), O['module'], O['thread']), 1) 84 | O['target'] = "w" 85 | O['key'] = NODE_KEY 86 | #O['depth'] = 5 # notice 87 | O['server_url'] = SERVER + "?m=node&a=" 88 | O['web-ports'] = util.csv2array(O['web-ports']) 89 | O['app-ports'] = util.csv2array(O['app-ports']) 90 | O['file-ext'] = util.csv2array(O['file-ext']) 91 | O['module'] = util.csv2array(O['module']) 92 | g.config(O) 93 | # print g.O 94 | info = scanner() 95 | urls = [] 96 | if info['web']: 97 | target = Url("http://" + O['target']) 98 | crawler = Crawler(target) 99 | crawler.parse(GetRequest(target)) 100 | urls.append(crawler) 101 | 102 | module = {} 103 | module_list = ["sqli", "xss"] 104 | task_queue = Queue.Queue() 105 | for item, target in itertools.product(module_list, urls): 106 | module[item] = __import__(item) 107 | for request in target.requests: 108 | task_queue.put({"module":item, "request":request}) 109 | 110 | g.O['thread'] = g.O['thread'] if g.O['thread'] > task_queue.qsize() else task_queue.qsize() 111 | 112 | work_manager = WorkManager(task_queue, int(g.O['thread'])) 113 | work_manager.wait_allcomplete() 114 | util.msg("All task done!!!",1) 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /Node/PlayWeb/test.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/test.pyc -------------------------------------------------------------------------------- /Node/PlayWeb/util.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | """ 3 | * @id PlayWeb-2014-3-28 4 | * @desc 工具函数库 5 | * @author Yaseng WwW.Yaseng.Me [Yaseng@UAUC.NET] 6 | * @project github.com/yaseng/playweb 7 | """ 8 | import json, urllib2, urllib, time 9 | from base64 import b64encode, b64decode 10 | import string 11 | import g 12 | from urllib import urlencode, quote 13 | 14 | def msg(text, type=0): 15 | if type == 2 and g.O['debug']==1: 16 | print "[d]"+str(text) 17 | elif type == 0: 18 | str_def = "[*]" 19 | elif type == 1: 20 | str_def = "[+]" 21 | elif type == -1: 22 | str_def = "[-]"; 23 | print str_def + text 24 | 25 | def date(d): 26 | return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(d)) 27 | 28 | def http_get(url, headers=None, time=5): 29 | ret = {} 30 | try: 31 | r = urllib2.urlopen(url, timeout=time) 32 | ret = {"data":r.read(), "code":200, "headers":r.headers} 33 | except urllib2.HTTPError, e: 34 | ret = {"data":e.read(), "code":e.code, "headers":e.headers} 35 | except urllib2.URLError, e: 36 | return None 37 | return ret 38 | """ 39 | @desc http post 40 | """ 41 | 42 | def http_post(url, data, headers=None, time=5): 43 | ret = {} 44 | try: 45 | opener = urllib2.build_opener() 46 | # opener.addheaders.append(('Cookie', ' 47 | # dict(r['headers']).get('content-length', 0) 48 | r = opener.open(url, data, timeout=time) 49 | ret = {"data":r.read(), "code":200, "headers":r.headers} 50 | except urllib2.HTTPError, e: 51 | ret = {"data":e.read(), "code":e.code, "headers":e.headers} 52 | except urllib2.URLError, e: 53 | return None 54 | return ret 55 | 56 | def csv2array(csv): 57 | items = csv.split(',') 58 | res = [] 59 | for i, item in enumerate(items): 60 | item = item.strip() 61 | if item != '': 62 | res.append(item) 63 | return res 64 | 65 | def encode_str(unicodeString, key=None): 66 | strorg = unicodeString.encode('utf-8') 67 | strlength = len(strorg) 68 | baselength = len(key) 69 | hh = [] 70 | for i in range(strlength): 71 | hh.append(chr((ord(strorg[i]) + ord(key[i % baselength])) % 256)) 72 | return b64encode(''.join(hh)) 73 | 74 | def decode_str(orig, key=None): 75 | strorg = b64decode(orig.encode('utf-8')) 76 | strlength = len(strorg) 77 | keylength = len(key) 78 | mystr = ' ' * strlength 79 | hh = [] 80 | for i in range(strlength): 81 | hh.append((ord(strorg[i]) - ord(key[i % keylength])) % 256) 82 | return ''.join(chr(i) for i in hh).decode('utf-8') 83 | 84 | def url2ip(url): 85 | return "" 86 | 87 | def json_encode(dict): 88 | return json.dumps(dict) 89 | 90 | def encode_dict(dict, key=None): 91 | return encode_str(json.dumps(dict), key) 92 | 93 | def report(dict): 94 | dict['project_hash'] = g.O['project_hash'] 95 | http_post(g.O['server_url'] + "report", "content=" + quote(encode_dict(dict, g.O['key']))) 96 | 97 | 98 | -------------------------------------------------------------------------------- /Node/PlayWeb/util.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/util.pyc -------------------------------------------------------------------------------- /Node/PlayWeb/x.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | """ 3 | * @id PlayWeb-2014-3-28 4 | * @desc 扫描节点入口 5 | * @author Yaseng WwW.Yaseng.Me [Yaseng@UAUC.NET] 6 | * @project github.com/yaseng/playweb 7 | """ 8 | import os, time, itertools, sys, Queue, threading, itertools 9 | from crawler import * 10 | from scanner import * 11 | import util, g 12 | reload(sys) 13 | sys.setdefaultencoding('utf8') 14 | 15 | class WorkManager(object): 16 | 17 | def __init__(self, queue, thread_num=2): 18 | self.work_queue = queue 19 | self.threads = [] 20 | self.__init_thread_pool(thread_num) 21 | 22 | 23 | 24 | def __init_thread_pool(self, thread_num): 25 | for i in range(thread_num): 26 | self.threads.append(Work(self.work_queue)) 27 | 28 | 29 | 30 | 31 | def add_job(self, func, *args): 32 | self.work_queue.put((func, list(args))) 33 | 34 | 35 | 36 | def check_queue(self): 37 | return self.work_queue.qsize() 38 | 39 | 40 | 41 | def wait_allcomplete(self): 42 | for item in self.threads: 43 | if item.isAlive(): 44 | item.join() 45 | 46 | class Work(threading.Thread): 47 | def __init__(self, work_queue): 48 | threading.Thread.__init__(self) 49 | self.work_queue = work_queue 50 | self.start() 51 | 52 | def run(self): 53 | while True: 54 | try: 55 | item = self.work_queue.get(block=False) 56 | print type(item) 57 | task = task_queue.get() 58 | module[task['module']].exploit(task['request']) 59 | self.work_queue.task_done() 60 | except Exception, e: 61 | #print str(e) 62 | break 63 | 64 | class Worker(threading.Thread): 65 | def __init__(self): 66 | threading.Thread.__init__(self) 67 | def run(self): 68 | while 1: 69 | if task_queue.empty() == True: 70 | break 71 | task = task_queue.get() 72 | module[task['module']].exploit(task['request']) 73 | 74 | if __name__ == '__main__': 75 | 76 | 77 | O = {} 78 | NODE_KEY = "a88b92531ba974f68bc1fd5938fc77" 79 | NODE_DEBUG = 0 80 | SERVER = "http://w/uauc/playweb/" 81 | util.msg("PlayWeb Node 1.0") 82 | util.msg("Server:%s Key:%s Debug:%d" % (SERVER, NODE_KEY, NODE_DEBUG)) 83 | util.msg("Listening server project...") 84 | while 1: 85 | r = util.http_get(SERVER + "/index.php?m=node&a=get_task") 86 | if r['data'] != " " : 87 | O = eval(util.decode_str(r['data'], NODE_KEY)) 88 | break 89 | time.sleep(1) 90 | O['debug'] = NODE_DEBUG 91 | util.msg("[Project] Target:%s Time:%s Module:%s Thread:%s" % (O['target'], util.date(O['start_time']), O['module'], O['thread']), 1) 92 | O['target'] = "w" 93 | O['key'] = NODE_KEY 94 | #O['depth'] = 5 # notice 95 | O['server_url'] = SERVER + "?m=node&a=" 96 | O['web-ports'] = util.csv2array(O['web-ports']) 97 | O['app-ports'] = util.csv2array(O['app-ports']) 98 | O['file-ext'] = util.csv2array(O['file-ext']) 99 | O['module'] = util.csv2array(O['module']) 100 | g.config(O) 101 | # print g.O 102 | info = scanner() 103 | urls = [] 104 | if info['web']: 105 | target = Url("http://" + O['target']) 106 | crawler = Crawler(target) 107 | crawler.parse(GetRequest(target)) 108 | urls.append(crawler) 109 | 110 | module = {} 111 | module_list = ["sqli", "xss"] 112 | task_queue = Queue.Queue() 113 | for item, target in itertools.product(module_list, urls): 114 | module[item] = __import__(item) 115 | for request in target.requests: 116 | task_queue.put({"module":item, "request":request}) 117 | 118 | g.O['thread'] = g.O['thread'] if g.O['thread'] > task_queue.qsize() else task_queue.qsize() 119 | 120 | work_manager = WorkManager(task_queue, int(g.O['thread'])) 121 | work_manager.wait_allcomplete() 122 | util.msg("All task done!!!",1) 123 | 124 | #=========================================================================== 125 | # for t in range(int(g.O['thread'])): 126 | # Worker().start() 127 | # 128 | # util.msg("Done", 1) 129 | #=========================================================================== 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /Node/PlayWeb/xss.py: -------------------------------------------------------------------------------- 1 | import itertools,util 2 | from http import Url, GetRequest, PostRequest 3 | 4 | 5 | XSS_POCS = [u'', u'', u'">'] 6 | 7 | 8 | def exploit(request): 9 | if not request.url.params and not request.fields: 10 | return 11 | if isinstance(request, GetRequest): 12 | for param, poc in itertools.product(request.url.params, XSS_POCS): 13 | req_tmp = request.copy() 14 | req_tmp.__class__ = GetRequest 15 | req_tmp.setParam(param, req_tmp.getParam(param)+poc) 16 | if poc in req_tmp.fetch(): 17 | #print "xss vulnerability param:%s info:%s" % (param, req_tmp) 18 | util.report({"type":"xss","content":util.json_encode({"xss_type":"GET","param":param,"detail":"%s" % req_tmp})}) 19 | break 20 | else: 21 | for field, poc in itertools.product(request.fields, XSS_POCS): 22 | req_tmp = request.copy() 23 | req_tmp.__class__ = PostRequest 24 | req_tmp.setField(field, req_tmp.getField(field)+poc) 25 | if poc in req_tmp.fetch(): 26 | #print "xss vulnerability param:%s info:%s" % (field, req_tmp) 27 | util.report({"type":"xss","content":util.json_encode({"xss_type":"POST","field":field,"detail":"%s" % req_tmp})}) 28 | break 29 | -------------------------------------------------------------------------------- /Node/PlayWeb/xss.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Node/PlayWeb/xss.pyc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | playweb 2 | ======= 3 | /** 4 | * @id note.txt-2014-3-2 5 | * @desc PlayWeb ReadMe 6 | * @author Yaseng WwW.Yaseng.Me [Yaseng@UAUC.NET] 7 | * @project github.com/yaseng/playweb 8 | **/ 9 | -------------------------------------------------------------------------------- /Static/css/bootstrap-wizard.css: -------------------------------------------------------------------------------- 1 | .wizard { 2 | display:none; 3 | } 4 | .wizard-modal form { 5 | margin:0; 6 | padding:0; 7 | } 8 | .wizard-modal.modal { 9 | width:750px; 10 | margin-left:-375px; 11 | top:50%; 12 | } 13 | .wizard-modal-footer { 14 | padding: 0px; 15 | text-align:right; 16 | } 17 | .wizard-modal-header.modal-header h3 { 18 | line-height:35px; 19 | display:inline 20 | } 21 | .wizard-modal-header.modal-header { 22 | border-bottom: 0; 23 | } 24 | 25 | .wizard-subtitle { 26 | font-weight:bold; 27 | color: #AFAFAF; 28 | padding-left:20px; 29 | } 30 | 31 | .wizard-error, 32 | .wizard-failure, 33 | .wizard-success, 34 | .wizard-loading, 35 | .wizard-card { 36 | position:relative; 37 | padding:35px; 38 | padding-top:20px; 39 | overflow-y: auto; 40 | height:300px; 41 | display:none; 42 | border-top: 1px solid #EEE; 43 | margin-right: 5px; 44 | } 45 | 46 | .wizard-nav-link .icon-chevron-right { 47 | float: right; 48 | margin-top: 12px; 49 | margin-right: -6px; 50 | opacity: .25; 51 | } 52 | 53 | li.wizard-nav-item.active .icon-chevron-right { 54 | opacity: 1; 55 | } 56 | 57 | li.wizard-nav-item { 58 | line-height:40px; 59 | } 60 | 61 | .wizard-modal.modal .nav-list > li > a { 62 | background-color:#f5f5f5; 63 | padding: 3px 15px 3px 20px; 64 | cursor: default; 65 | color:#B4B4B4; 66 | } 67 | 68 | .wizard-modal.modal .nav-list li.active > a { 69 | background-color:#08C; 70 | } 71 | 72 | .wizard-modal.modal .nav-list > li.already-visited > a.wizard-nav-link { 73 | color: #08C; 74 | cursor: pointer; 75 | } 76 | 77 | .wizard-modal.modal .nav-list > li.active > a.wizard-nav-link { 78 | color:white; 79 | } 80 | 81 | .already-visited > a.wizard-nav-link:hover { 82 | background-color: #E4E4E4; 83 | } 84 | 85 | .wizard-card > h3 { 86 | margin-top: 0; 87 | margin-bottom: 20px; 88 | font-size: 21px; 89 | line-height: 40px; 90 | font-weight: normal; 91 | } 92 | 93 | .wizard-progress { 94 | padding:15px; 95 | bottom:0; 96 | } 97 | .wizard-progress-container { 98 | padding:20px; 99 | } 100 | 101 | .wizard-steps { 102 | width:28%; 103 | height:425px; 104 | background-color:#f5f5f5; 105 | } 106 | 107 | .wizard-nav-container { 108 | height:360px; 109 | } 110 | 111 | .nav > li > a.wizard-step-error { 112 | background-color:#F2DEDE; 113 | color:#B94A48; 114 | font-weight:bold; 115 | } 116 | 117 | .wizard-step-error .icon-chevron-right { 118 | opacity: 0; 119 | } 120 | 121 | .wizard-input-section { 122 | margin-bottom:20px; 123 | } 124 | 125 | .wizard-buttons-container { 126 | padding:20px; 127 | } 128 | 129 | .wizard-modal .popover.error-popover { 130 | background-color:#F2DEDE; 131 | color:#B94A48; 132 | border-color:#953B39; 133 | } 134 | 135 | .wizard-modal .popover.error-popover .arrow::after { 136 | border-right-color:#F2DEDE; 137 | } 138 | 139 | .wizard-modal .popover.error-popover .popover-title { 140 | display:none; 141 | } 142 | 143 | .wizard-modal .popover.error-popover .arrow { 144 | border-right-color:#953B39; 145 | } -------------------------------------------------------------------------------- /Static/css/green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/css/green.png -------------------------------------------------------------------------------- /Static/css/green@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/css/green@2x.png -------------------------------------------------------------------------------- /Static/img/8642.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/8642.png -------------------------------------------------------------------------------- /Static/img/android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/android.png -------------------------------------------------------------------------------- /Static/img/apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/apple.png -------------------------------------------------------------------------------- /Static/img/flattr-badge-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/flattr-badge-large.png -------------------------------------------------------------------------------- /Static/img/gb_tip_layer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/gb_tip_layer.png -------------------------------------------------------------------------------- /Static/img/gb_tip_layer_ie6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/gb_tip_layer_ie6.png -------------------------------------------------------------------------------- /Static/img/gb_tip_loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/gb_tip_loading.gif -------------------------------------------------------------------------------- /Static/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /Static/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /Static/img/linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/linux.png -------------------------------------------------------------------------------- /Static/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/loading.gif -------------------------------------------------------------------------------- /Static/img/windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/Static/img/windows.png -------------------------------------------------------------------------------- /Static/js/icheck.min.js: -------------------------------------------------------------------------------- 1 | /*! iCheck v1.0.2 by Damir Sultanov, http://git.io/arlzeA, MIT Licensed */ 2 | (function(f){function A(a,b,d){var c=a[0],g=/er/.test(d)?_indeterminate:/bl/.test(d)?n:k,e=d==_update?{checked:c[k],disabled:c[n],indeterminate:"true"==a.attr(_indeterminate)||"false"==a.attr(_determinate)}:c[g];if(/^(ch|di|in)/.test(d)&&!e)x(a,g);else if(/^(un|en|de)/.test(d)&&e)q(a,g);else if(d==_update)for(var f in e)e[f]?x(a,f,!0):q(a,f,!0);else if(!b||"toggle"==d){if(!b)a[_callback]("ifClicked");e?c[_type]!==r&&q(a,g):x(a,g)}}function x(a,b,d){var c=a[0],g=a.parent(),e=b==k,u=b==_indeterminate, 3 | v=b==n,s=u?_determinate:e?y:"enabled",F=l(a,s+t(c[_type])),B=l(a,b+t(c[_type]));if(!0!==c[b]){if(!d&&b==k&&c[_type]==r&&c.name){var w=a.closest("form"),p='input[name="'+c.name+'"]',p=w.length?w.find(p):f(p);p.each(function(){this!==c&&f(this).data(m)&&q(f(this),b)})}u?(c[b]=!0,c[k]&&q(a,k,"force")):(d||(c[b]=!0),e&&c[_indeterminate]&&q(a,_indeterminate,!1));D(a,e,b,d)}c[n]&&l(a,_cursor,!0)&&g.find("."+C).css(_cursor,"default");g[_add](B||l(a,b)||"");g.attr("role")&&!u&&g.attr("aria-"+(v?n:k),"true"); 4 | g[_remove](F||l(a,s)||"")}function q(a,b,d){var c=a[0],g=a.parent(),e=b==k,f=b==_indeterminate,m=b==n,s=f?_determinate:e?y:"enabled",q=l(a,s+t(c[_type])),r=l(a,b+t(c[_type]));if(!1!==c[b]){if(f||!d||"force"==d)c[b]=!1;D(a,e,s,d)}!c[n]&&l(a,_cursor,!0)&&g.find("."+C).css(_cursor,"pointer");g[_remove](r||l(a,b)||"");g.attr("role")&&!f&&g.attr("aria-"+(m?n:k),"false");g[_add](q||l(a,s)||"")}function E(a,b){if(a.data(m)){a.parent().html(a.attr("style",a.data(m).s||""));if(b)a[_callback](b);a.off(".i").unwrap(); 5 | f(_label+'[for="'+a[0].id+'"]').add(a.closest(_label)).off(".i")}}function l(a,b,f){if(a.data(m))return a.data(m).o[b+(f?"":"Class")]}function t(a){return a.charAt(0).toUpperCase()+a.slice(1)}function D(a,b,f,c){if(!c){if(b)a[_callback]("ifToggled");a[_callback]("ifChanged")[_callback]("if"+t(f))}}var m="iCheck",C=m+"-helper",r="radio",k="checked",y="un"+k,n="disabled";_determinate="determinate";_indeterminate="in"+_determinate;_update="update";_type="type";_click="click";_touch="touchbegin.i touchend.i"; 6 | _add="addClass";_remove="removeClass";_callback="trigger";_label="label";_cursor="cursor";_mobile=/ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent);f.fn[m]=function(a,b){var d='input[type="checkbox"], input[type="'+r+'"]',c=f(),g=function(a){a.each(function(){var a=f(this);c=a.is(d)?c.add(a):c.add(a.find(d))})};if(/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(a))return a=a.toLowerCase(),g(this),c.each(function(){var c= 7 | f(this);"destroy"==a?E(c,"ifDestroyed"):A(c,!0,a);f.isFunction(b)&&b()});if("object"!=typeof a&&a)return this;var e=f.extend({checkedClass:k,disabledClass:n,indeterminateClass:_indeterminate,labelHover:!0},a),l=e.handle,v=e.hoverClass||"hover",s=e.focusClass||"focus",t=e.activeClass||"active",B=!!e.labelHover,w=e.labelHoverClass||"hover",p=(""+e.increaseArea).replace("%","")|0;if("checkbox"==l||l==r)d='input[type="'+l+'"]';-50>p&&(p=-50);g(this);return c.each(function(){var a=f(this);E(a);var c=this, 8 | b=c.id,g=-p+"%",d=100+2*p+"%",d={position:"absolute",top:g,left:g,display:"block",width:d,height:d,margin:0,padding:0,background:"#fff",border:0,opacity:0},g=_mobile?{position:"absolute",visibility:"hidden"}:p?d:{position:"absolute",opacity:0},l="checkbox"==c[_type]?e.checkboxClass||"icheckbox":e.radioClass||"i"+r,z=f(_label+'[for="'+b+'"]').add(a.closest(_label)),u=!!e.aria,y=m+"-"+Math.random().toString(36).substr(2,6),h='
")[_callback]("ifCreated").parent().append(e.insert);d=f('').css(d).appendTo(h);a.data(m,{o:e,s:a.attr("style")}).css(g);e.inheritClass&&h[_add](c.className||"");e.inheritID&&b&&h.attr("id",m+"-"+b);"static"==h.css("position")&&h.css("position","relative");A(a,!0,_update);if(z.length)z.on(_click+".i mouseover.i mouseout.i "+_touch,function(b){var d=b[_type],e=f(this);if(!c[n]){if(d==_click){if(f(b.target).is("a"))return; 10 | A(a,!1,!0)}else B&&(/ut|nd/.test(d)?(h[_remove](v),e[_remove](w)):(h[_add](v),e[_add](w)));if(_mobile)b.stopPropagation();else return!1}});a.on(_click+".i focus.i blur.i keyup.i keydown.i keypress.i",function(b){var d=b[_type];b=b.keyCode;if(d==_click)return!1;if("keydown"==d&&32==b)return c[_type]==r&&c[k]||(c[k]?q(a,k):x(a,k)),!1;if("keyup"==d&&c[_type]==r)!c[k]&&x(a,k);else if(/us|ur/.test(d))h["blur"==d?_remove:_add](s)});d.on(_click+" mousedown mouseup mouseover mouseout "+_touch,function(b){var d= 11 | b[_type],e=/wn|up/.test(d)?t:v;if(!c[n]){if(d==_click)A(a,!1,!0);else{if(/wn|er|in/.test(d))h[_add](e);else h[_remove](e+" "+t);if(z.length&&B&&e==v)z[/ut|nd/.test(d)?_remove:_add](w)}if(_mobile)b.stopPropagation();else return!1}})})}})(window.jQuery||window.Zepto); 12 | -------------------------------------------------------------------------------- /Static/js/index.js: -------------------------------------------------------------------------------- 1 | var isScanning=0; 2 | $(function() { 3 | 4 | $('input[name=radio-targets]').on('ifChecked', 5 | function(event) { 6 | 7 | }); 8 | 9 | $('input').iCheck({ 10 | checkboxClass: 'icheckbox_flat-green', 11 | radioClass: 'iradio_flat-green', 12 | increaseArea: '20%' 13 | }); 14 | 15 | $('input[name="node[1]"],input[name="moudle[port]"],input[name="moudle[crawler]"],input[name="moudle[sqli]"],input[name="moudle[xss]"],input[name="moudle[lfi]"],input[name="moudle[ftp-brute]"]').iCheck('check'); 16 | 17 | $.fn.wizard.logging = true; 18 | var wizard = $("#project-wizard").wizard(); 19 | $("#btn-scanner").click(function() { 20 | wizard.reset(); 21 | wizard.show(); 22 | }); 23 | 24 | wizard.on("submit", 25 | function(wizard) { 26 | 27 | data = wizard.serialize(); 28 | $('input[name=wd]').attr("value", $('input[name=target]').val()); 29 | $('input[name=wd]').attr("disabled", 'disabled'); 30 | isScanning = 1; 31 | 32 | $("#container-onfo").hide(); 33 | $("#container-result").slideDown(555); 34 | 35 | $.post("http://w/uauc/playweb/index.php?m=project&a=test", data, 36 | function(d) { 37 | 38 | // console.log(d); 39 | var str1 = '1' + d.target + '100% '; 40 | $("#project-list").append(str1); 41 | 42 | }); 43 | 44 | wizard.reset().close(); 45 | $("#loader").show(); 46 | 47 | }); 48 | setTimeout(getOnlineNode, 2000); 49 | 50 | }); 51 | 52 | function hacking() { 53 | 54 | var wd = $('input[name=wd]').val(); 55 | $('input[name=wd]').attr("disabled", 'disabled'); 56 | // var type=$('select[name=type]').val(); 57 | $("#loader").show(); 58 | 59 | return false; 60 | 61 | if (wd) { 62 | 63 | isScanning = 1; 64 | setting.target = wd; 65 | $("#container-onfo").hide(); 66 | $("#container-result").slideDown(555); 67 | 68 | $.post("?m=project&a=on_add", setting, 69 | function(d) { 70 | 71 | var str1 = '1' + d.target + '100% '; 72 | $("#project-list").append(str1); 73 | 74 | }); 75 | 76 | } 77 | 78 | return false; 79 | 80 | } 81 | 82 | function getOnlineNode() { 83 | 84 | if (isScanning == 0) { 85 | 86 | setTimeout(getOnlineNode, 2000); 87 | $.get("?m=node&a=listing", 88 | function(nodes) { 89 | 90 | node_list_html = ""; 91 | node_icon = "" 92 | for (i in nodes) { 93 | 94 | if (nodes[i].os == "Windows") { 95 | 96 | node_icon = ' '; 97 | 98 | } else if (nodes[i].os == "Linux") { 99 | 100 | node_icon = ' '; 101 | } 102 | node_list_html += node_icon + "" + nodes[i].ip + " "; 103 | 104 | } 105 | 106 | $("#node_list").html(node_list_html); 107 | 108 | }); 109 | 110 | } 111 | 112 | } 113 | 114 | function check_target(el){ 115 | 116 | var val = el.val(); 117 | ret = {status: true}; 118 | if(val==""){ 119 | ret.status = false; 120 | ret.msg = "错误的ip或url"; 121 | } 122 | 123 | return ret; 124 | 125 | } 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /Static/js/uauc.js: -------------------------------------------------------------------------------- 1 |  2 | 3 | var setting={"plugin":"1,4,6","node":"70a1527626a1393,68bc1fd5938fc99","web_port":"80,8080,81,8081,8181,8088","cookie":"sdafaf","target":""} 4 | 5 | 6 | $(function() { 7 | 8 | 9 | $('.selectpicker').selectpicker(); 10 | $("#lable-setting").html(JSON.stringify(setting)); 11 | //setTimeout(getOnlineNode,2000); 12 | 13 | 14 | }); 15 | 16 | 17 | 18 | 19 | 20 | function viewReport(){ 21 | 22 | 23 | } 24 | 25 | function log(str){ 26 | 27 | $("#log").show(); 28 | //$("#log").append(str); 29 | 30 | } 31 | function loading(){ 32 | 33 | $("#dbtable").hide(555); 34 | $("#retable").hide(200); 35 | //$("tbody").empty(); 36 | $("#retable").show(555); 37 | 38 | 39 | } 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /ThinkPHP/Common/runtime.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP 运行时文件 编译后不再加载 14 | * @category Think 15 | * @package Common 16 | * @author liu21st 17 | */ 18 | defined('THINK_PATH') or exit(); 19 | if(version_compare(PHP_VERSION,'5.2.0','<')) die('require PHP > 5.2.0 !'); 20 | 21 | // 版本信息 22 | define('THINK_VERSION', '3.1.3'); 23 | 24 | // 系统信息 25 | if(version_compare(PHP_VERSION,'5.4.0','<')) { 26 | ini_set('magic_quotes_runtime',0); 27 | define('MAGIC_QUOTES_GPC',get_magic_quotes_gpc()?True:False); 28 | }else{ 29 | define('MAGIC_QUOTES_GPC',false); 30 | } 31 | define('IS_CGI',substr(PHP_SAPI, 0,3)=='cgi' ? 1 : 0 ); 32 | define('IS_WIN',strstr(PHP_OS, 'WIN') ? 1 : 0 ); 33 | define('IS_CLI',PHP_SAPI=='cli'? 1 : 0); 34 | 35 | // 项目名称 36 | defined('APP_NAME') or define('APP_NAME', basename(dirname($_SERVER['SCRIPT_FILENAME']))); 37 | 38 | if(!IS_CLI) { 39 | // 当前文件名 40 | if(!defined('_PHP_FILE_')) { 41 | if(IS_CGI) { 42 | //CGI/FASTCGI模式下 43 | $_temp = explode('.php',$_SERVER['PHP_SELF']); 44 | define('_PHP_FILE_', rtrim(str_replace($_SERVER['HTTP_HOST'],'',$_temp[0].'.php'),'/')); 45 | }else { 46 | define('_PHP_FILE_', rtrim($_SERVER['SCRIPT_NAME'],'/')); 47 | } 48 | } 49 | if(!defined('__ROOT__')) { 50 | // 网站URL根目录 51 | if( strtoupper(APP_NAME) == strtoupper(basename(dirname(_PHP_FILE_))) ) { 52 | $_root = dirname(dirname(_PHP_FILE_)); 53 | }else { 54 | $_root = dirname(_PHP_FILE_); 55 | } 56 | define('__ROOT__', (($_root=='/' || $_root=='\\')?'':$_root)); 57 | } 58 | 59 | //支持的URL模式 60 | define('URL_COMMON', 0); //普通模式 61 | define('URL_PATHINFO', 1); //PATHINFO模式 62 | define('URL_REWRITE', 2); //REWRITE模式 63 | define('URL_COMPAT', 3); // 兼容模式 64 | } 65 | 66 | // 路径设置 可在入口文件中重新定义 所有路径常量都必须以/ 结尾 67 | defined('CORE_PATH') or define('CORE_PATH', THINK_PATH.'Lib/'); // 系统核心类库目录 68 | defined('EXTEND_PATH') or define('EXTEND_PATH', THINK_PATH.'Extend/'); // 系统扩展目录 69 | defined('MODE_PATH') or define('MODE_PATH', EXTEND_PATH.'Mode/'); // 模式扩展目录 70 | defined('ENGINE_PATH') or define('ENGINE_PATH', EXTEND_PATH.'Engine/'); // 引擎扩展目录 71 | defined('VENDOR_PATH') or define('VENDOR_PATH', EXTEND_PATH.'Vendor/'); // 第三方类库目录 72 | defined('LIBRARY_PATH') or define('LIBRARY_PATH', EXTEND_PATH.'Library/'); // 扩展类库目录 73 | defined('COMMON_PATH') or define('COMMON_PATH', APP_PATH.'Common/'); // 项目公共目录 74 | defined('LIB_PATH') or define('LIB_PATH', APP_PATH.'Lib/'); // 项目类库目录 75 | defined('CONF_PATH') or define('CONF_PATH', APP_PATH.'Conf/'); // 项目配置目录 76 | defined('LANG_PATH') or define('LANG_PATH', APP_PATH.'Lang/'); // 项目语言包目录 77 | defined('TMPL_PATH') or define('TMPL_PATH', APP_PATH.'Tpl/'); // 项目模板目录 78 | defined('HTML_PATH') or define('HTML_PATH', APP_PATH.'Html/'); // 项目静态目录 79 | defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH.'Logs/'); // 项目日志目录 80 | defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH.'Temp/'); // 项目缓存目录 81 | defined('DATA_PATH') or define('DATA_PATH', RUNTIME_PATH.'Data/'); // 项目数据目录 82 | defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH.'Cache/'); // 项目模板缓存目录 83 | 84 | // 为了方便导入第三方类库 设置Vendor目录到include_path 85 | set_include_path(get_include_path() . PATH_SEPARATOR . VENDOR_PATH); 86 | 87 | // 加载运行时所需要的文件 并负责自动目录生成 88 | function load_runtime_file() { 89 | // 加载系统基础函数库 90 | require THINK_PATH.'Common/common.php'; 91 | // 读取核心文件列表 92 | $list = array( 93 | CORE_PATH.'Core/Think.class.php', 94 | CORE_PATH.'Core/ThinkException.class.php', // 异常处理类 95 | CORE_PATH.'Core/Behavior.class.php', 96 | ); 97 | // 加载模式文件列表 98 | foreach ($list as $key=>$file){ 99 | if(is_file($file)) require_cache($file); 100 | } 101 | // 加载系统类库别名定义 102 | alias_import(include THINK_PATH.'Conf/alias.php'); 103 | 104 | // 检查项目目录结构 如果不存在则自动创建 105 | if(!is_dir(LIB_PATH)) { 106 | // 创建项目目录结构 107 | build_app_dir(); 108 | }elseif(!is_dir(CACHE_PATH)){ 109 | // 检查缓存目录 110 | check_runtime(); 111 | }elseif(APP_DEBUG){ 112 | // 调试模式切换删除编译缓存 113 | if(is_file(RUNTIME_FILE)) unlink(RUNTIME_FILE); 114 | } 115 | } 116 | 117 | // 检查缓存目录(Runtime) 如果不存在则自动创建 118 | function check_runtime() { 119 | if(!is_dir(RUNTIME_PATH)) { 120 | mkdir(RUNTIME_PATH); 121 | }elseif(!is_writeable(RUNTIME_PATH)) { 122 | header('Content-Type:text/html; charset=utf-8'); 123 | exit('目录 [ '.RUNTIME_PATH.' ] 不可写!'); 124 | } 125 | mkdir(CACHE_PATH); // 模板缓存目录 126 | if(!is_dir(LOG_PATH)) mkdir(LOG_PATH); // 日志目录 127 | if(!is_dir(TEMP_PATH)) mkdir(TEMP_PATH); // 数据缓存目录 128 | if(!is_dir(DATA_PATH)) mkdir(DATA_PATH); // 数据文件目录 129 | return true; 130 | } 131 | 132 | // 创建编译缓存 133 | function build_runtime_cache($append='') { 134 | // 生成编译文件 135 | $defs = get_defined_constants(TRUE); 136 | $content = '$GLOBALS[\'_beginTime\'] = microtime(TRUE);'; 137 | if(defined('RUNTIME_DEF_FILE')) { // 编译后的常量文件外部引入 138 | file_put_contents(RUNTIME_DEF_FILE,'$item){ 169 | foreach ($item as $key=>$name) { 170 | $content .= is_int($key)?compile(CORE_PATH.'Behavior/'.$name.'Behavior.class.php'):compile($name); 171 | } 172 | } 173 | return $content; 174 | } 175 | 176 | // 创建项目目录结构 177 | function build_app_dir() { 178 | // 没有创建项目目录的话自动创建 179 | if(!is_dir(APP_PATH)) mkdir(APP_PATH,0755,true); 180 | if(is_writeable(APP_PATH)) { 181 | $dirs = array( 182 | LIB_PATH, 183 | RUNTIME_PATH, 184 | CONF_PATH, 185 | COMMON_PATH, 186 | LANG_PATH, 187 | CACHE_PATH, 188 | TMPL_PATH, 189 | TMPL_PATH.C('DEFAULT_THEME').'/', 190 | LOG_PATH, 191 | TEMP_PATH, 192 | DATA_PATH, 193 | LIB_PATH.'Model/', 194 | LIB_PATH.'Action/', 195 | LIB_PATH.'Behavior/', 196 | LIB_PATH.'Widget/', 197 | ); 198 | foreach ($dirs as $dir){ 199 | if(!is_dir($dir)) mkdir($dir,0755,true); 200 | } 201 | // 写入目录安全文件 202 | build_dir_secure($dirs); 203 | // 写入初始配置文件 204 | if(!is_file(CONF_PATH.'config.php')) 205 | file_put_contents(CONF_PATH.'config.php',"'配置值'\n);\n?>"); 206 | // 写入测试Action 207 | if(!is_file(LIB_PATH.'Action/IndexAction.class.php')) 208 | build_first_action(); 209 | }else{ 210 | header('Content-Type:text/html; charset=utf-8'); 211 | exit('项目目录不可写,目录无法自动生成!
请使用项目生成器或者手动生成项目目录~'); 212 | } 213 | } 214 | 215 | // 创建测试Action 216 | function build_first_action() { 217 | $content = file_get_contents(THINK_PATH.'Tpl/default_index.tpl'); 218 | file_put_contents(LIB_PATH.'Action/IndexAction.class.php',$content); 219 | } 220 | 221 | // 生成目录安全文件 222 | function build_dir_secure($dirs='') { 223 | // 目录安全写入 224 | if(defined('BUILD_DIR_SECURE') && BUILD_DIR_SECURE) { 225 | defined('DIR_SECURE_FILENAME') or define('DIR_SECURE_FILENAME', 'index.html'); 226 | defined('DIR_SECURE_CONTENT') or define('DIR_SECURE_CONTENT', ' '); 227 | // 自动写入目录安全文件 228 | $content = DIR_SECURE_CONTENT; 229 | $files = explode(',', DIR_SECURE_FILENAME); 230 | foreach ($files as $filename){ 231 | foreach ($dirs as $dir) 232 | file_put_contents($dir.$filename,$content); 233 | } 234 | } 235 | } 236 | 237 | // 加载运行时所需文件 238 | load_runtime_file(); 239 | // 记录加载文件时间 240 | G('loadTime'); 241 | // 执行入口 242 | Think::Start(); -------------------------------------------------------------------------------- /ThinkPHP/Conf/alias.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | // 系统别名定义文件 14 | return array( 15 | 'Model' => CORE_PATH.'Core/Model.class.php', 16 | 'Db' => CORE_PATH.'Core/Db.class.php', 17 | 'Log' => CORE_PATH.'Core/Log.class.php', 18 | 'ThinkTemplate' => CORE_PATH.'Template/ThinkTemplate.class.php', 19 | 'TagLib' => CORE_PATH.'Template/TagLib.class.php', 20 | 'Cache' => CORE_PATH.'Core/Cache.class.php', 21 | 'Widget' => CORE_PATH.'Core/Widget.class.php', 22 | 'TagLibCx' => CORE_PATH.'Driver/TagLib/TagLibCx.class.php', 23 | ); -------------------------------------------------------------------------------- /ThinkPHP/Conf/convention.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP惯例配置文件 14 | * 该文件请不要修改,如果要覆盖惯例配置的值,可在项目配置文件中设定和惯例不符的配置项 15 | * 配置名称大小写任意,系统会统一转换成小写 16 | * 所有配置参数都可以在生效前动态改变 17 | * @category Think 18 | * @package Common 19 | * @author liu21st 20 | * @version $Id: convention.php 3088 2012-07-29 09:12:19Z luofei614@gmail.com $ 21 | */ 22 | defined('THINK_PATH') or exit(); 23 | return array( 24 | /* 项目设定 */ 25 | 'APP_STATUS' => 'debug', // 应用调试模式状态 调试模式开启后有效 默认为debug 可扩展 并自动加载对应的配置文件 26 | 'APP_FILE_CASE' => false, // 是否检查文件的大小写 对Windows平台有效 27 | 'APP_AUTOLOAD_PATH' => '',// 自动加载机制的自动搜索路径,注意搜索顺序 28 | 'APP_TAGS_ON' => true, // 系统标签扩展开关 29 | 'APP_SUB_DOMAIN_DEPLOY' => false, // 是否开启子域名部署 30 | 'APP_SUB_DOMAIN_RULES' => array(), // 子域名部署规则 31 | 'APP_SUB_DOMAIN_DENY' => array(), // 子域名禁用列表 32 | 'APP_GROUP_LIST' => '', // 项目分组设定,多个组之间用逗号分隔,例如'Home,Admin' 33 | 'APP_GROUP_MODE' => 0, // 分组模式 0 普通分组 1 独立分组 34 | 'APP_GROUP_PATH' => 'Modules', // 分组目录 独立分组模式下面有效 35 | 'ACTION_SUFFIX' => '', // 操作方法后缀 36 | 37 | /* Cookie设置 */ 38 | 'COOKIE_EXPIRE' => 0, // Coodie有效期 39 | 'COOKIE_DOMAIN' => '', // Cookie有效域名 40 | 'COOKIE_PATH' => '/', // Cookie路径 41 | 'COOKIE_PREFIX' => '', // Cookie前缀 避免冲突 42 | 43 | /* 默认设定 */ 44 | 'DEFAULT_M_LAYER' => 'Model', // 默认的模型层名称 45 | 'DEFAULT_C_LAYER' => 'Action', // 默认的控制器层名称 46 | 'DEFAULT_V_LAYER' => 'Tpl', // 默认的视图层名称 47 | 'DEFAULT_APP' => '@', // 默认项目名称,@表示当前项目 48 | 'DEFAULT_LANG' => 'zh-cn', // 默认语言 49 | 'DEFAULT_THEME' => '', // 默认模板主题名称 50 | 'DEFAULT_GROUP' => 'Home', // 默认分组 51 | 'DEFAULT_MODULE' => 'Index', // 默认模块名称 52 | 'DEFAULT_ACTION' => 'index', // 默认操作名称 53 | 'DEFAULT_CHARSET' => 'utf-8', // 默认输出编码 54 | 'DEFAULT_TIMEZONE' => 'PRC', // 默认时区 55 | 'DEFAULT_AJAX_RETURN' => 'JSON', // 默认AJAX 数据返回格式,可选JSON XML ... 56 | 'DEFAULT_JSONP_HANDLER' => 'jsonpReturn', // 默认JSONP格式返回的处理方法 57 | 'DEFAULT_FILTER' => 'htmlspecialchars', // 默认参数过滤方法 用于 $this->_get('变量名');$this->_post('变量名')... 58 | 59 | /* 数据库设置 */ 60 | 'DB_TYPE' => 'mysql', // 数据库类型 61 | 'DB_HOST' => 'localhost', // 服务器地址 62 | 'DB_NAME' => '', // 数据库名 63 | 'DB_USER' => 'root', // 用户名 64 | 'DB_PWD' => '', // 密码 65 | 'DB_PORT' => '', // 端口 66 | 'DB_PREFIX' => 'think_', // 数据库表前缀 67 | 'DB_FIELDTYPE_CHECK' => false, // 是否进行字段类型检查 68 | 'DB_FIELDS_CACHE' => true, // 启用字段缓存 69 | 'DB_CHARSET' => 'utf8', // 数据库编码默认采用utf8 70 | 'DB_DEPLOY_TYPE' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 71 | 'DB_RW_SEPARATE' => false, // 数据库读写是否分离 主从式有效 72 | 'DB_MASTER_NUM' => 1, // 读写分离后 主服务器数量 73 | 'DB_SLAVE_NO' => '', // 指定从服务器序号 74 | 'DB_SQL_BUILD_CACHE' => false, // 数据库查询的SQL创建缓存 75 | 'DB_SQL_BUILD_QUEUE' => 'file', // SQL缓存队列的缓存方式 支持 file xcache和apc 76 | 'DB_SQL_BUILD_LENGTH' => 20, // SQL缓存的队列长度 77 | 'DB_SQL_LOG' => false, // SQL执行日志记录 78 | 79 | /* 数据缓存设置 */ 80 | 'DATA_CACHE_TIME' => 0, // 数据缓存有效期 0表示永久缓存 81 | 'DATA_CACHE_COMPRESS' => false, // 数据缓存是否压缩缓存 82 | 'DATA_CACHE_CHECK' => false, // 数据缓存是否校验缓存 83 | 'DATA_CACHE_PREFIX' => '', // 缓存前缀 84 | 'DATA_CACHE_TYPE' => 'File', // 数据缓存类型,支持:File|Db|Apc|Memcache|Shmop|Sqlite|Xcache|Apachenote|Eaccelerator 85 | 'DATA_CACHE_PATH' => TEMP_PATH,// 缓存路径设置 (仅对File方式缓存有效) 86 | 'DATA_CACHE_SUBDIR' => false, // 使用子目录缓存 (自动根据缓存标识的哈希创建子目录) 87 | 'DATA_PATH_LEVEL' => 1, // 子目录缓存级别 88 | 89 | /* 错误设置 */ 90 | 'ERROR_MESSAGE' => '页面错误!请稍后再试~',//错误显示信息,非调试模式有效 91 | 'ERROR_PAGE' => '', // 错误定向页面 92 | 'SHOW_ERROR_MSG' => false, // 显示错误信息 93 | 'TRACE_EXCEPTION' => false, // TRACE错误信息是否抛异常 针对trace方法 94 | 95 | /* 日志设置 */ 96 | 'LOG_RECORD' => false, // 默认不记录日志 97 | 'LOG_TYPE' => 3, // 日志记录类型 0 系统 1 邮件 3 文件 4 SAPI 默认为文件方式 98 | 'LOG_DEST' => '', // 日志记录目标 99 | 'LOG_EXTRA' => '', // 日志记录额外信息 100 | 'LOG_LEVEL' => 'EMERG,ALERT,CRIT,ERR',// 允许记录的日志级别 101 | 'LOG_FILE_SIZE' => 2097152, // 日志文件大小限制 102 | 'LOG_EXCEPTION_RECORD' => false, // 是否记录异常信息日志 103 | 104 | /* SESSION设置 */ 105 | 'SESSION_AUTO_START' => true, // 是否自动开启Session 106 | 'SESSION_OPTIONS' => array(), // session 配置数组 支持type name id path expire domain 等参数 107 | 'SESSION_TYPE' => '', // session hander类型 默认无需设置 除非扩展了session hander驱动 108 | 'SESSION_PREFIX' => '', // session 前缀 109 | //'VAR_SESSION_ID' => 'session_id', //sessionID的提交变量 110 | 111 | /* 模板引擎设置 */ 112 | 'TMPL_CONTENT_TYPE' => 'text/html', // 默认模板输出类型 113 | 'TMPL_ACTION_ERROR' => THINK_PATH.'Tpl/dispatch_jump.tpl', // 默认错误跳转对应的模板文件 114 | 'TMPL_ACTION_SUCCESS' => THINK_PATH.'Tpl/dispatch_jump.tpl', // 默认成功跳转对应的模板文件 115 | 'TMPL_EXCEPTION_FILE' => THINK_PATH.'Tpl/think_exception.tpl',// 异常页面的模板文件 116 | 'TMPL_DETECT_THEME' => false, // 自动侦测模板主题 117 | 'TMPL_TEMPLATE_SUFFIX' => '.html', // 默认模板文件后缀 118 | 'TMPL_FILE_DEPR' => '/', //模板文件MODULE_NAME与ACTION_NAME之间的分割符 119 | 120 | /* URL设置 */ 121 | 'URL_CASE_INSENSITIVE' => false, // 默认false 表示URL区分大小写 true则表示不区分大小写 122 | 'URL_MODEL' => 1, // URL访问模式,可选参数0、1、2、3,代表以下四种模式: 123 | // 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE 模式); 3 (兼容模式) 默认为PATHINFO 模式,提供最好的用户体验和SEO支持 124 | 'URL_PATHINFO_DEPR' => '/', // PATHINFO模式下,各参数之间的分割符号 125 | 'URL_PATHINFO_FETCH' => 'ORIG_PATH_INFO,REDIRECT_PATH_INFO,REDIRECT_URL', // 用于兼容判断PATH_INFO 参数的SERVER替代变量列表 126 | 'URL_HTML_SUFFIX' => 'html', // URL伪静态后缀设置 127 | 'URL_DENY_SUFFIX' => 'ico|png|gif|jpg', // URL禁止访问的后缀设置 128 | 'URL_PARAMS_BIND' => true, // URL变量绑定到Action方法参数 129 | 'URL_404_REDIRECT' => '', // 404 跳转页面 部署模式有效 130 | 131 | /* 系统变量名称设置 */ 132 | 'VAR_GROUP' => 'g', // 默认分组获取变量 133 | 'VAR_MODULE' => 'm', // 默认模块获取变量 134 | 'VAR_ACTION' => 'a', // 默认操作获取变量 135 | 'VAR_AJAX_SUBMIT' => 'ajax', // 默认的AJAX提交变量 136 | 'VAR_JSONP_HANDLER' => 'callback', 137 | 'VAR_PATHINFO' => 's', // PATHINFO 兼容模式获取变量例如 ?s=/module/action/id/1 后面的参数取决于URL_PATHINFO_DEPR 138 | 'VAR_URL_PARAMS' => '_URL_', // PATHINFO URL参数变量 139 | 'VAR_TEMPLATE' => 't', // 默认模板切换变量 140 | 'VAR_FILTERS' => 'filter_exp', // 全局系统变量的默认过滤方法 多个用逗号分割 141 | 142 | 'OUTPUT_ENCODE' => false, // 页面压缩输出 143 | 'HTTP_CACHE_CONTROL' => 'private', // 网页缓存控制 144 | 145 | ); -------------------------------------------------------------------------------- /ThinkPHP/Conf/debug.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP 默认的调试模式配置文件 14 | * 如果项目有定义自己的调试模式配置文件,本文件无效 15 | * @category Think 16 | * @package Common 17 | * @author liu21st 18 | * @version $Id: debug.php 3071 2012-07-15 07:59:23Z liu21st@gmail.com $ 19 | */ 20 | defined('THINK_PATH') or exit(); 21 | // 调试模式下面默认设置 可以在项目配置目录下重新定义 debug.php 覆盖 22 | return array( 23 | 'LOG_RECORD' => true, // 进行日志记录 24 | 'LOG_EXCEPTION_RECORD' => true, // 是否记录异常信息日志 25 | 'LOG_LEVEL' => 'EMERG,ALERT,CRIT,ERR,WARN,NOTIC,INFO,DEBUG,SQL', // 允许记录的日志级别 26 | 'DB_FIELDS_CACHE' => false, // 字段缓存信息 27 | 'DB_SQL_LOG' => true, // 记录SQL信息 28 | 'APP_FILE_CASE' => true, // 是否检查文件的大小写 对Windows平台有效 29 | 'TMPL_CACHE_ON' => false, // 是否开启模板编译缓存,设为false则每次都会重新编译 30 | 'TMPL_STRIP_SPACE' => false, // 是否去除模板文件里面的html空格与换行 31 | 'SHOW_ERROR_MSG' => true, // 显示错误信息 32 | ); -------------------------------------------------------------------------------- /ThinkPHP/Conf/tags.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | // 系统默认的核心行为扩展列表文件 13 | return array( 14 | 'app_init' => array( 15 | ), 16 | 'app_begin' => array( 17 | 'ReadHtmlCache', // 读取静态缓存 18 | ), 19 | 'route_check' => array( 20 | 'CheckRoute', // 路由检测 21 | ), 22 | 'app_end' => array(), 23 | 'path_info' => array(), 24 | 'action_begin' => array(), 25 | 'action_end' => array(), 26 | 'view_begin' => array(), 27 | 'view_parse' => array( 28 | 'ParseTemplate', // 模板解析 支持PHP、内置模板引擎和第三方模板引擎 29 | ), 30 | 'view_filter' => array( 31 | 'ContentReplace', // 模板输出替换 32 | 'TokenBuild', // 表单令牌 33 | 'WriteHtmlCache', // 写入静态缓存 34 | 'ShowRuntime', // 运行时间显示 35 | ), 36 | 'view_end' => array( 37 | 'ShowPageTrace', // 页面Trace显示 38 | ), 39 | ); -------------------------------------------------------------------------------- /ThinkPHP/Extend/README.txt: -------------------------------------------------------------------------------- 1 |  2 | Extend目录为系统扩展目录(核心版不含任何扩展),子目录结构为: 3 | 4 | |-Action 控制器扩展 5 | |-Behavior 行为扩展 6 | |-Driver 驱动扩展 7 | | ├Driver/Cache 缓存驱动 8 | | ├Driver/Db 数据库驱动 9 | | ├Driver/Session SESSION驱动 10 | | ├Driver/TagLib 标签库驱动 11 | | ├Driver/Template 模板引擎驱动 12 | | 13 | |-Engine 引擎扩展 14 | |-Function 函数扩展 15 | |-Library 类库扩展 16 | | ├ORG ORG类库包 17 | | ├COM COM类库包 18 | | 19 | |-Mode 模式扩展 20 | |-Model 模型扩展 21 | |-Tool 其他扩展或工具 22 | |-Vendor 第三方类库目录 23 | 24 | 关于扩展的详细使用,请参考开发手册的扩展章节。 -------------------------------------------------------------------------------- /ThinkPHP/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 3 | 版权所有Copyright © 2006-2012 by ThinkPHP (http://thinkphp.cn) 4 | All rights reserved。 5 | ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 6 | 7 | Apache Licence是著名的非盈利开源组织Apache采用的协议。 8 | 该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, 9 | 允许代码修改,再作为开源或商业软件发布。需要满足 10 | 的条件: 11 | 1. 需要给代码的用户一份Apache Licence ; 12 | 2. 如果你修改了代码,需要在被修改的文件中说明; 13 | 3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 14 | 带有原来代码中的协议,商标,专利声明和其他原来作者规 15 | 定需要包含的说明; 16 | 4. 如果再发布的产品中包含一个Notice文件,则在Notice文 17 | 件中需要带有本协议内容。你可以在Notice中增加自己的 18 | 许可,但不可以表现为对Apache Licence构成更改。 19 | 具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /ThinkPHP/Lang/en-us.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP English language package 14 | * @category Think 15 | * @package Lang 16 | * @author liu21st 17 | * @version $Id: zh-cn.php 3034 2012-10-17 21:14:00Z yangweijiester@gmail.com $ 18 | */ 19 | return array( 20 | // core 21 | '_MODULE_NOT_EXIST_' => 'Module can not been loaded', 22 | '_ERROR_ACTION_' => 'Error action', 23 | '_LANGUAGE_NOT_LOAD_' => 'Can\'t load language package', 24 | '_TEMPLATE_NOT_EXIST_' => 'Template does\'t exist', 25 | '_MODULE_' => 'Module', 26 | '_ACTION_' => 'Action', 27 | '_ACTION_NOT_EXIST_' => 'Action does\'t exist Or not defined', 28 | '_MODEL_NOT_EXIST_' => 'Model does\'t exist Or not defined', 29 | '_VALID_ACCESS_' => 'No access', 30 | '_XML_TAG_ERROR_' => 'XML tag syntax errors', 31 | '_DATA_TYPE_INVALID_' => 'Invlid data type!', 32 | '_OPERATION_WRONG_' => 'Operation error occurs', 33 | '_NOT_LOAD_DB_' => 'Unable to load the database', 34 | '_NO_DB_DRIVER_' => 'Unable to load database driver', 35 | '_NOT_SUPPORT_DB_' => 'The system is temporarily not support database', 36 | '_NO_DB_CONFIG_' => 'Not define the database configuration', 37 | '_NOT_SUPPERT_' => 'The system does not support', 38 | '_CACHE_TYPE_INVALID_' => 'Unable to load the cache type', 39 | '_FILE_NOT_WRITEABLE_' => 'Directory (file) is not writable', 40 | '_METHOD_NOT_EXIST_' => 'The method you requested does not exist!', 41 | '_CLASS_NOT_EXIST_' => 'Instantiating a class does not exist!', 42 | '_CLASS_CONFLICT_' => 'Class name conflicts', 43 | '_TEMPLATE_ERROR_' => 'Template Engine errors', 44 | '_CACHE_WRITE_ERROR_' => 'Cache file write failed!', 45 | '_TAGLIB_NOT_EXIST_' => 'Tag library is not defined', 46 | '_OPERATION_FAIL_' => 'Operation failed!', 47 | '_OPERATION_SUCCESS_' => 'Operation successed!', 48 | '_SELECT_NOT_EXIST_' => 'Record does not exist!', 49 | '_EXPRESS_ERROR_' => 'Expression errors', 50 | '_TOKEN_ERROR_' => 'Form\'s token errors', 51 | '_RECORD_HAS_UPDATE_' => 'Record has been updated', 52 | '_NOT_ALLOW_PHP_' => 'PHP codes are not allowed in the template', 53 | '_PARAM_ERROR_' => 'Parameter error or undefined', 54 | ); -------------------------------------------------------------------------------- /ThinkPHP/Lang/zh-cn.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP 简体中文语言包 14 | * @category Think 15 | * @package Lang 16 | * @author liu21st 17 | */ 18 | return array( 19 | // 核心 20 | '_MODULE_NOT_EXIST_' => '无法加载模块', 21 | '_ERROR_ACTION_' => '非法操作', 22 | '_LANGUAGE_NOT_LOAD_' => '无法加载语言包', 23 | '_TEMPLATE_NOT_EXIST_' => '模板不存在', 24 | '_MODULE_' => '模块', 25 | '_ACTION_' => '操作', 26 | '_ACTION_NOT_EXIST_' => '控制器不存在或者没有定义', 27 | '_MODEL_NOT_EXIST_' => '模型不存在或者没有定义', 28 | '_VALID_ACCESS_' => '没有权限', 29 | '_XML_TAG_ERROR_' => 'XML标签语法错误', 30 | '_DATA_TYPE_INVALID_' => '非法数据对象!', 31 | '_OPERATION_WRONG_' => '操作出现错误', 32 | '_NOT_LOAD_DB_' => '无法加载数据库', 33 | '_NO_DB_DRIVER_' => '无法加载数据库驱动', 34 | '_NOT_SUPPORT_DB_' => '系统暂时不支持数据库', 35 | '_NO_DB_CONFIG_' => '没有定义数据库配置', 36 | '_NOT_SUPPERT_' => '系统不支持', 37 | '_CACHE_TYPE_INVALID_' => '无法加载缓存类型', 38 | '_FILE_NOT_WRITEABLE_' => '目录(文件)不可写', 39 | '_METHOD_NOT_EXIST_' => '您所请求的方法不存在!', 40 | '_CLASS_NOT_EXIST_' => '实例化一个不存在的类!', 41 | '_CLASS_CONFLICT_' => '类名冲突', 42 | '_TEMPLATE_ERROR_' => '模板引擎错误', 43 | '_CACHE_WRITE_ERROR_' => '缓存文件写入失败!', 44 | '_TAGLIB_NOT_EXIST_' => '标签库未定义', 45 | '_OPERATION_FAIL_' => '操作失败!', 46 | '_OPERATION_SUCCESS_' => '操作成功!', 47 | '_SELECT_NOT_EXIST_' => '记录不存在!', 48 | '_EXPRESS_ERROR_' => '表达式错误', 49 | '_TOKEN_ERROR_' => '表单令牌错误', 50 | '_RECORD_HAS_UPDATE_' => '记录已经更新', 51 | '_NOT_ALLOW_PHP_' => '模板禁用PHP代码', 52 | '_PARAM_ERROR_' => '参数错误或者未定义', 53 | ); -------------------------------------------------------------------------------- /ThinkPHP/Lib/Behavior/CheckRouteBehavior.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | /** 14 | * 系统行为扩展:路由检测 15 | * @category Think 16 | * @package Think 17 | * @subpackage Behavior 18 | * @author liu21st 19 | */ 20 | class CheckRouteBehavior extends Behavior { 21 | // 行为参数定义(默认值) 可在项目配置中覆盖 22 | protected $options = array( 23 | 'URL_ROUTER_ON' => false, // 是否开启URL路由 24 | 'URL_ROUTE_RULES' => array(), // 默认路由规则,注:分组配置无法替代 25 | ); 26 | 27 | // 行为扩展的执行入口必须是run 28 | public function run(&$return){ 29 | // 优先检测是否存在PATH_INFO 30 | $regx = trim($_SERVER['PATH_INFO'],'/'); 31 | if(empty($regx)) return $return = true; 32 | // 是否开启路由使用 33 | if(!C('URL_ROUTER_ON')) return $return = false; 34 | // 路由定义文件优先于config中的配置定义 35 | $routes = C('URL_ROUTE_RULES'); 36 | // 路由处理 37 | if(!empty($routes)) { 38 | $depr = C('URL_PATHINFO_DEPR'); 39 | // 分隔符替换 确保路由定义使用统一的分隔符 40 | $regx = str_replace($depr,'/',$regx); 41 | foreach ($routes as $rule=>$route){ 42 | if(0===strpos($rule,'/') && preg_match($rule,$regx,$matches)) { // 正则路由 43 | return $return = $this->parseRegex($matches,$route,$regx); 44 | }else{ // 规则路由 45 | $len1 = substr_count($regx,'/'); 46 | $len2 = substr_count($rule,'/'); 47 | if($len1>=$len2) { 48 | if('$' == substr($rule,-1,1)) {// 完整匹配 49 | if($len1 != $len2) { 50 | continue; 51 | }else{ 52 | $rule = substr($rule,0,-1); 53 | } 54 | } 55 | $match = $this->checkUrlMatch($regx,$rule); 56 | if($match) return $return = $this->parseRule($rule,$route,$regx); 57 | } 58 | } 59 | } 60 | } 61 | $return = false; 62 | } 63 | 64 | // 检测URL和规则路由是否匹配 65 | private function checkUrlMatch($regx,$rule) { 66 | $m1 = explode('/',$regx); 67 | $m2 = explode('/',$rule); 68 | $match = true; // 是否匹配 69 | foreach ($m2 as $key=>$val){ 70 | if(':' == substr($val,0,1)) {// 动态变量 71 | if(strpos($val,'\\')) { 72 | $type = substr($val,-1); 73 | if('d'==$type && !is_numeric($m1[$key])) { 74 | $match = false; 75 | break; 76 | } 77 | }elseif(strpos($val,'^')){ 78 | $array = explode('|',substr(strstr($val,'^'),1)); 79 | if(in_array($m1[$key],$array)) { 80 | $match = false; 81 | break; 82 | } 83 | } 84 | }elseif(0 !== strcasecmp($val,$m1[$key])){ 85 | $match = false; 86 | break; 87 | } 88 | } 89 | return $match; 90 | } 91 | 92 | // 解析规范的路由地址 93 | // 地址格式 [分组/模块/操作?]参数1=值1&参数2=值2... 94 | private function parseUrl($url) { 95 | $var = array(); 96 | if(false !== strpos($url,'?')) { // [分组/模块/操作?]参数1=值1&参数2=值2... 97 | $info = parse_url($url); 98 | $path = explode('/',$info['path']); 99 | parse_str($info['query'],$var); 100 | }elseif(strpos($url,'/')){ // [分组/模块/操作] 101 | $path = explode('/',$url); 102 | }else{ // 参数1=值1&参数2=值2... 103 | parse_str($url,$var); 104 | } 105 | if(isset($path)) { 106 | $var[C('VAR_ACTION')] = array_pop($path); 107 | if(!empty($path)) { 108 | $var[C('VAR_MODULE')] = array_pop($path); 109 | } 110 | if(!empty($path)) { 111 | $var[C('VAR_GROUP')] = array_pop($path); 112 | } 113 | } 114 | return $var; 115 | } 116 | 117 | // 解析规则路由 118 | // '路由规则'=>'[分组/模块/操作]?额外参数1=值1&额外参数2=值2...' 119 | // '路由规则'=>array('[分组/模块/操作]','额外参数1=值1&额外参数2=值2...') 120 | // '路由规则'=>'外部地址' 121 | // '路由规则'=>array('外部地址','重定向代码') 122 | // 路由规则中 :开头 表示动态变量 123 | // 外部地址中可以用动态变量 采用 :1 :2 的方式 124 | // 'news/:month/:day/:id'=>array('News/read?cate=1','status=1'), 125 | // 'new/:id'=>array('/new.php?id=:1',301), 重定向 126 | private function parseRule($rule,$route,$regx) { 127 | // 获取路由地址规则 128 | $url = is_array($route)?$route[0]:$route; 129 | // 获取URL地址中的参数 130 | $paths = explode('/',$regx); 131 | // 解析路由规则 132 | $matches = array(); 133 | $rule = explode('/',$rule); 134 | foreach ($rule as $item){ 135 | if(0===strpos($item,':')) { // 动态变量获取 136 | if($pos = strpos($item,'^') ) { 137 | $var = substr($item,1,$pos-1); 138 | }elseif(strpos($item,'\\')){ 139 | $var = substr($item,1,-2); 140 | }else{ 141 | $var = substr($item,1); 142 | } 143 | $matches[$var] = array_shift($paths); 144 | }else{ // 过滤URL中的静态变量 145 | array_shift($paths); 146 | } 147 | } 148 | if(0=== strpos($url,'/') || 0===strpos($url,'http')) { // 路由重定向跳转 149 | if(strpos($url,':')) { // 传递动态参数 150 | $values = array_values($matches); 151 | $url = preg_replace('/:(\d+)/e','$values[\\1-1]',$url); 152 | } 153 | header("Location: $url", true,(is_array($route) && isset($route[1]))?$route[1]:301); 154 | exit; 155 | }else{ 156 | // 解析路由地址 157 | $var = $this->parseUrl($url); 158 | // 解析路由地址里面的动态参数 159 | $values = array_values($matches); 160 | foreach ($var as $key=>$val){ 161 | if(0===strpos($val,':')) { 162 | $var[$key] = $values[substr($val,1)-1]; 163 | } 164 | } 165 | $var = array_merge($matches,$var); 166 | // 解析剩余的URL参数 167 | if($paths) { 168 | preg_replace('@(\w+)\/([^\/]+)@e', '$var[strtolower(\'\\1\')]=strip_tags(\'\\2\');', implode('/',$paths)); 169 | } 170 | // 解析路由自动传入参数 171 | if(is_array($route) && isset($route[1])) { 172 | parse_str($route[1],$params); 173 | $var = array_merge($var,$params); 174 | } 175 | $_GET = array_merge($var,$_GET); 176 | } 177 | return true; 178 | } 179 | 180 | // 解析正则路由 181 | // '路由正则'=>'[分组/模块/操作]?参数1=值1&参数2=值2...' 182 | // '路由正则'=>array('[分组/模块/操作]?参数1=值1&参数2=值2...','额外参数1=值1&额外参数2=值2...') 183 | // '路由正则'=>'外部地址' 184 | // '路由正则'=>array('外部地址','重定向代码') 185 | // 参数值和外部地址中可以用动态变量 采用 :1 :2 的方式 186 | // '/new\/(\d+)\/(\d+)/'=>array('News/read?id=:1&page=:2&cate=1','status=1'), 187 | // '/new\/(\d+)/'=>array('/new.php?id=:1&page=:2&status=1','301'), 重定向 188 | private function parseRegex($matches,$route,$regx) { 189 | // 获取路由地址规则 190 | $url = is_array($route)?$route[0]:$route; 191 | $url = preg_replace('/:(\d+)/e','$matches[\\1]',$url); 192 | if(0=== strpos($url,'/') || 0===strpos($url,'http')) { // 路由重定向跳转 193 | header("Location: $url", true,(is_array($route) && isset($route[1]))?$route[1]:301); 194 | exit; 195 | }else{ 196 | // 解析路由地址 197 | $var = $this->parseUrl($url); 198 | // 解析剩余的URL参数 199 | $regx = substr_replace($regx,'',0,strlen($matches[0])); 200 | if($regx) { 201 | preg_replace('@(\w+)\/([^,\/]+)@e', '$var[strtolower(\'\\1\')]=strip_tags(\'\\2\');', $regx); 202 | } 203 | // 解析路由自动传入参数 204 | if(is_array($route) && isset($route[1])) { 205 | parse_str($route[1],$params); 206 | $var = array_merge($var,$params); 207 | } 208 | $_GET = array_merge($var,$_GET); 209 | } 210 | return true; 211 | } 212 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Behavior/ContentReplaceBehavior.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | /** 14 | * 系统行为扩展:模板内容输出替换 15 | * @category Think 16 | * @package Think 17 | * @subpackage Behavior 18 | * @author liu21st 19 | */ 20 | class ContentReplaceBehavior extends Behavior { 21 | // 行为参数定义 22 | protected $options = array( 23 | 'TMPL_PARSE_STRING' => array(), 24 | ); 25 | 26 | // 行为扩展的执行入口必须是run 27 | public function run(&$content){ 28 | $content = $this->templateContentReplace($content); 29 | } 30 | 31 | /** 32 | * 模板内容替换 33 | * @access protected 34 | * @param string $content 模板内容 35 | * @return string 36 | */ 37 | protected function templateContentReplace($content) { 38 | // 系统默认的特殊变量替换 39 | $replace = array( 40 | '__TMPL__' => APP_TMPL_PATH, // 项目模板目录 41 | '__ROOT__' => __ROOT__, // 当前网站地址 42 | '__APP__' => __APP__, // 当前项目地址 43 | '__GROUP__' => defined('GROUP_NAME')?__GROUP__:__APP__, 44 | '__ACTION__' => __ACTION__, // 当前操作地址 45 | '__SELF__' => __SELF__, // 当前页面地址 46 | '__URL__' => __URL__, 47 | '../Public' => APP_TMPL_PATH.'Public',// 项目公共模板目录 48 | '__PUBLIC__' => __ROOT__.'/Public',// 站点公共目录 49 | ); 50 | // 允许用户自定义模板的字符串替换 51 | if(is_array(C('TMPL_PARSE_STRING')) ) 52 | $replace = array_merge($replace,C('TMPL_PARSE_STRING')); 53 | $content = str_replace(array_keys($replace),array_values($replace),$content); 54 | return $content; 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Behavior/ParseTemplateBehavior.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | /** 14 | * 系统行为扩展:模板解析 15 | * @category Think 16 | * @package Think 17 | * @subpackage Behavior 18 | * @author liu21st 19 | */ 20 | class ParseTemplateBehavior extends Behavior { 21 | // 行为参数定义(默认值) 可在项目配置中覆盖 22 | protected $options = array( 23 | // 布局设置 24 | 'TMPL_ENGINE_TYPE' => 'Think', // 默认模板引擎 以下设置仅对使用Think模板引擎有效 25 | 'TMPL_CACHFILE_SUFFIX' => '.php', // 默认模板缓存后缀 26 | 'TMPL_DENY_FUNC_LIST' => 'echo,exit', // 模板引擎禁用函数 27 | 'TMPL_DENY_PHP' => false, // 默认模板引擎是否禁用PHP原生代码 28 | 'TMPL_L_DELIM' => '{', // 模板引擎普通标签开始标记 29 | 'TMPL_R_DELIM' => '}', // 模板引擎普通标签结束标记 30 | 'TMPL_VAR_IDENTIFY' => 'array', // 模板变量识别。留空自动判断,参数为'obj'则表示对象 31 | 'TMPL_STRIP_SPACE' => true, // 是否去除模板文件里面的html空格与换行 32 | 'TMPL_CACHE_ON' => true, // 是否开启模板编译缓存,设为false则每次都会重新编译 33 | 'TMPL_CACHE_PREFIX' => '', // 模板缓存前缀标识,可以动态改变 34 | 'TMPL_CACHE_TIME' => 0, // 模板缓存有效期 0 为永久,(以数字为值,单位:秒) 35 | 'TMPL_LAYOUT_ITEM' => '{__CONTENT__}', // 布局模板的内容替换标识 36 | 'LAYOUT_ON' => false, // 是否启用布局 37 | 'LAYOUT_NAME' => 'layout', // 当前布局名称 默认为layout 38 | 39 | // Think模板引擎标签库相关设定 40 | 'TAGLIB_BEGIN' => '<', // 标签库标签开始标记 41 | 'TAGLIB_END' => '>', // 标签库标签结束标记 42 | 'TAGLIB_LOAD' => true, // 是否使用内置标签库之外的其它标签库,默认自动检测 43 | 'TAGLIB_BUILD_IN' => 'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序 44 | 'TAGLIB_PRE_LOAD' => '', // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔 45 | ); 46 | 47 | // 行为扩展的执行入口必须是run 48 | public function run(&$_data){ 49 | $engine = strtolower(C('TMPL_ENGINE_TYPE')); 50 | $_content = empty($_data['content'])?$_data['file']:$_data['content']; 51 | $_data['prefix'] = !empty($_data['prefix'])?$_data['prefix']:C('TMPL_CACHE_PREFIX'); 52 | if('think'==$engine){ // 采用Think模板引擎 53 | if((!empty($_data['content']) && $this->checkContentCache($_data['content'],$_data['prefix'])) 54 | || $this->checkCache($_data['file'],$_data['prefix'])) { // 缓存有效 55 | // 分解变量并载入模板缓存 56 | extract($_data['var'], EXTR_OVERWRITE); 57 | //载入模版缓存文件 58 | include C('CACHE_PATH').$_data['prefix'].md5($_content).C('TMPL_CACHFILE_SUFFIX'); 59 | }else{ 60 | $tpl = Think::instance('ThinkTemplate'); 61 | // 编译并加载模板文件 62 | $tpl->fetch($_content,$_data['var'],$_data['prefix']); 63 | } 64 | }else{ 65 | // 调用第三方模板引擎解析和输出 66 | $class = 'Template'.ucwords($engine); 67 | if(class_exists($class)) { 68 | $tpl = new $class; 69 | $tpl->fetch($_content,$_data['var']); 70 | }else { // 类没有定义 71 | throw_exception(L('_NOT_SUPPERT_').': ' . $class); 72 | } 73 | } 74 | } 75 | 76 | /** 77 | * 检查缓存文件是否有效 78 | * 如果无效则需要重新编译 79 | * @access public 80 | * @param string $tmplTemplateFile 模板文件名 81 | * @return boolean 82 | */ 83 | protected function checkCache($tmplTemplateFile,$prefix='') { 84 | if (!C('TMPL_CACHE_ON')) // 优先对配置设定检测 85 | return false; 86 | $tmplCacheFile = C('CACHE_PATH').$prefix.md5($tmplTemplateFile).C('TMPL_CACHFILE_SUFFIX'); 87 | if(!is_file($tmplCacheFile)){ 88 | return false; 89 | }elseif (filemtime($tmplTemplateFile) > filemtime($tmplCacheFile)) { 90 | // 模板文件如果有更新则缓存需要更新 91 | return false; 92 | }elseif (C('TMPL_CACHE_TIME') != 0 && time() > filemtime($tmplCacheFile)+C('TMPL_CACHE_TIME')) { 93 | // 缓存是否在有效期 94 | return false; 95 | } 96 | // 开启布局模板 97 | if(C('LAYOUT_ON')) { 98 | $layoutFile = THEME_PATH.C('LAYOUT_NAME').C('TMPL_TEMPLATE_SUFFIX'); 99 | if(filemtime($layoutFile) > filemtime($tmplCacheFile)) { 100 | return false; 101 | } 102 | } 103 | // 缓存有效 104 | return true; 105 | } 106 | 107 | /** 108 | * 检查缓存内容是否有效 109 | * 如果无效则需要重新编译 110 | * @access public 111 | * @param string $tmplContent 模板内容 112 | * @return boolean 113 | */ 114 | protected function checkContentCache($tmplContent,$prefix='') { 115 | if(is_file(C('CACHE_PATH').$prefix.md5($tmplContent).C('TMPL_CACHFILE_SUFFIX'))){ 116 | return true; 117 | }else{ 118 | return false; 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Behavior/ReadHtmlCacheBehavior.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | /** 14 | * 系统行为扩展:静态缓存读取 15 | * @category Think 16 | * @package Think 17 | * @subpackage Behavior 18 | * @author liu21st 19 | */ 20 | class ReadHtmlCacheBehavior extends Behavior { 21 | protected $options = array( 22 | 'HTML_CACHE_ON' => false, 23 | 'HTML_CACHE_TIME' => 60, 24 | 'HTML_CACHE_RULES' => array(), 25 | 'HTML_FILE_SUFFIX' => '.html', 26 | ); 27 | 28 | // 行为扩展的执行入口必须是run 29 | public function run(&$params){ 30 | // 开启静态缓存 31 | if(C('HTML_CACHE_ON')) { 32 | $cacheTime = $this->requireHtmlCache(); 33 | if( false !== $cacheTime && $this->checkHTMLCache(HTML_FILE_NAME,$cacheTime)) { //静态页面有效 34 | // 读取静态页面输出 35 | readfile(HTML_FILE_NAME); 36 | exit(); 37 | } 38 | } 39 | } 40 | 41 | // 判断是否需要静态缓存 42 | static private function requireHtmlCache() { 43 | // 分析当前的静态规则 44 | $htmls = C('HTML_CACHE_RULES'); // 读取静态规则 45 | if(!empty($htmls)) { 46 | $htmls = array_change_key_case($htmls); 47 | // 静态规则文件定义格式 actionName=>array('静态规则','缓存时间','附加规则') 48 | // 'read'=>array('{id},{name}',60,'md5') 必须保证静态规则的唯一性 和 可判断性 49 | // 检测静态规则 50 | $moduleName = strtolower(MODULE_NAME); 51 | $actionName = strtolower(ACTION_NAME); 52 | if(isset($htmls[$moduleName.':'.$actionName])) { 53 | $html = $htmls[$moduleName.':'.$actionName]; // 某个模块的操作的静态规则 54 | }elseif(isset($htmls[$moduleName.':'])){// 某个模块的静态规则 55 | $html = $htmls[$moduleName.':']; 56 | }elseif(isset($htmls[$actionName])){ 57 | $html = $htmls[$actionName]; // 所有操作的静态规则 58 | }elseif(isset($htmls['*'])){ 59 | $html = $htmls['*']; // 全局静态规则 60 | }elseif(isset($htmls['empty:index']) && !class_exists(MODULE_NAME.'Action')){ 61 | $html = $htmls['empty:index']; // 空模块静态规则 62 | }elseif(isset($htmls[$moduleName.':_empty']) && $this->isEmptyAction(MODULE_NAME,ACTION_NAME)){ 63 | $html = $htmls[$moduleName.':_empty']; // 空操作静态规则 64 | } 65 | if(!empty($html)) { 66 | // 解读静态规则 67 | $rule = $html[0]; 68 | // 以$_开头的系统变量 69 | $rule = preg_replace('/{\$(_\w+)\.(\w+)\|(\w+)}/e',"\\3(\$\\1['\\2'])",$rule); 70 | $rule = preg_replace('/{\$(_\w+)\.(\w+)}/e',"\$\\1['\\2']",$rule); 71 | // {ID|FUN} GET变量的简写 72 | $rule = preg_replace('/{(\w+)\|(\w+)}/e',"\\2(\$_GET['\\1'])",$rule); 73 | $rule = preg_replace('/{(\w+)}/e',"\$_GET['\\1']",$rule); 74 | // 特殊系统变量 75 | $rule = str_ireplace( 76 | array('{:app}','{:module}','{:action}','{:group}'), 77 | array(APP_NAME,MODULE_NAME,ACTION_NAME,defined('GROUP_NAME')?GROUP_NAME:''), 78 | $rule); 79 | // {|FUN} 单独使用函数 80 | $rule = preg_replace('/{|(\w+)}/e',"\\1()",$rule); 81 | if(!empty($html[2])) $rule = $html[2]($rule); // 应用附加函数 82 | $cacheTime = isset($html[1])?$html[1]:C('HTML_CACHE_TIME'); // 缓存有效期 83 | // 当前缓存文件 84 | define('HTML_FILE_NAME',HTML_PATH . $rule.C('HTML_FILE_SUFFIX')); 85 | return $cacheTime; 86 | } 87 | } 88 | // 无需缓存 89 | return false; 90 | } 91 | 92 | /** 93 | * 检查静态HTML文件是否有效 94 | * 如果无效需要重新更新 95 | * @access public 96 | * @param string $cacheFile 静态文件名 97 | * @param integer $cacheTime 缓存有效期 98 | * @return boolean 99 | */ 100 | static public function checkHTMLCache($cacheFile='',$cacheTime='') { 101 | if(!is_file($cacheFile)){ 102 | return false; 103 | }elseif (filemtime(C('TEMPLATE_NAME')) > filemtime($cacheFile)) { 104 | // 模板文件如果更新静态文件需要更新 105 | return false; 106 | }elseif(!is_numeric($cacheTime) && function_exists($cacheTime)){ 107 | return $cacheTime($cacheFile); 108 | }elseif ($cacheTime != 0 && NOW_TIME > filemtime($cacheFile)+$cacheTime) { 109 | // 文件是否在有效期 110 | return false; 111 | } 112 | //静态文件有效 113 | return true; 114 | } 115 | 116 | //检测是否是空操作 117 | static private function isEmptyAction($module,$action) { 118 | $className = $module.'Action'; 119 | $class = new $className; 120 | return !method_exists($class,$action); 121 | } 122 | 123 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Behavior/ShowPageTraceBehavior.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | /** 14 | * 系统行为扩展:页面Trace显示输出 15 | * @category Think 16 | * @package Think 17 | * @subpackage Behavior 18 | * @author liu21st 19 | */ 20 | class ShowPageTraceBehavior extends Behavior { 21 | // 行为参数定义 22 | protected $options = array( 23 | 'SHOW_PAGE_TRACE' => false, // 显示页面Trace信息 24 | 'TRACE_PAGE_TABS' => array('BASE'=>'基本','FILE'=>'文件','INFO'=>'流程','ERR|NOTIC'=>'错误','SQL'=>'SQL','DEBUG'=>'调试'), // 页面Trace可定制的选项卡 25 | 'PAGE_TRACE_SAVE' => false, 26 | ); 27 | 28 | // 行为扩展的执行入口必须是run 29 | public function run(&$params){ 30 | if(!IS_AJAX && C('SHOW_PAGE_TRACE')) { 31 | echo $this->showTrace(); 32 | } 33 | } 34 | 35 | /** 36 | * 显示页面Trace信息 37 | * @access private 38 | */ 39 | private function showTrace() { 40 | // 系统默认显示信息 41 | $files = get_included_files(); 42 | $info = array(); 43 | foreach ($files as $key=>$file){ 44 | $info[] = $file.' ( '.number_format(filesize($file)/1024,2).' KB )'; 45 | } 46 | $trace = array(); 47 | $base = array( 48 | '请求信息' => date('Y-m-d H:i:s',$_SERVER['REQUEST_TIME']).' '.$_SERVER['SERVER_PROTOCOL'].' '.$_SERVER['REQUEST_METHOD'].' : '.__SELF__, 49 | '运行时间' => $this->showTime(), 50 | '吞吐率' => number_format(1/G('beginTime','viewEndTime'),2).'req/s', 51 | '内存开销' => MEMORY_LIMIT_ON?number_format((memory_get_usage() - $GLOBALS['_startUseMems'])/1024,2).' kb':'不支持', 52 | '查询信息' => N('db_query').' queries '.N('db_write').' writes ', 53 | '文件加载' => count(get_included_files()), 54 | '缓存信息' => N('cache_read').' gets '.N('cache_write').' writes ', 55 | '配置加载' => count(c()), 56 | '会话信息' => 'SESSION_ID='.session_id(), 57 | ); 58 | // 读取项目定义的Trace文件 59 | $traceFile = CONF_PATH.'trace.php'; 60 | if(is_file($traceFile)) { 61 | $base = array_merge($base,include $traceFile); 62 | } 63 | $debug = trace(); 64 | $tabs = C('TRACE_PAGE_TABS'); 65 | foreach ($tabs as $name=>$title){ 66 | switch(strtoupper($name)) { 67 | case 'BASE':// 基本信息 68 | $trace[$title] = $base; 69 | break; 70 | case 'FILE': // 文件信息 71 | $trace[$title] = $info; 72 | break; 73 | default:// 调试信息 74 | $name = strtoupper($name); 75 | if(strpos($name,'|')) {// 多组信息 76 | $array = explode('|',$name); 77 | $result = array(); 78 | foreach($array as $name){ 79 | $result += isset($debug[$name])?$debug[$name]:array(); 80 | } 81 | $trace[$title] = $result; 82 | }else{ 83 | $trace[$title] = isset($debug[$name])?$debug[$name]:''; 84 | } 85 | } 86 | } 87 | if($save = C('PAGE_TRACE_SAVE')) { // 保存页面Trace日志 88 | if(is_array($save)) {// 选择选项卡保存 89 | $tabs = C('TRACE_PAGE_TABS'); 90 | $array = array(); 91 | foreach ($save as $tab){ 92 | $array[] = $tabs[$tab]; 93 | } 94 | } 95 | $content = date('[ c ]').' '.get_client_ip().' '.$_SERVER['REQUEST_URI']."\r\n"; 96 | foreach ($trace as $key=>$val){ 97 | if(!isset($array) || in_array($key,$array)) { 98 | $content .= '[ '.$key." ]\r\n"; 99 | if(is_array($val)) { 100 | foreach ($val as $k=>$v){ 101 | $content .= (!is_numeric($k)?$k.':':'').print_r($v,true)."\r\n"; 102 | } 103 | }else{ 104 | $content .= print_r($val,true)."\r\n"; 105 | } 106 | $content .= "\r\n"; 107 | } 108 | } 109 | error_log(str_replace('
',"\r\n",$content), Log::FILE,LOG_PATH.date('y_m_d').'_trace.log'); 110 | } 111 | unset($files,$info,$base); 112 | // 调用Trace页面模板 113 | ob_start(); 114 | include C('TMPL_TRACE_FILE')?C('TMPL_TRACE_FILE'):THINK_PATH.'Tpl/page_trace.tpl'; 115 | return ob_get_clean(); 116 | } 117 | 118 | /** 119 | * 获取运行时间 120 | */ 121 | private function showTime() { 122 | // 显示运行时间 123 | G('beginTime',$GLOBALS['_beginTime']); 124 | G('viewEndTime'); 125 | // 显示详细运行时间 126 | return G('beginTime','viewEndTime').'s ( Load:'.G('beginTime','loadTime').'s Init:'.G('loadTime','initTime').'s Exec:'.G('initTime','viewStartTime').'s Template:'.G('viewStartTime','viewEndTime').'s )'; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /ThinkPHP/Lib/Behavior/ShowRuntimeBehavior.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | /** 14 | * 系统行为扩展:运行时间信息显示 15 | * @category Think 16 | * @package Think 17 | * @subpackage Behavior 18 | * @author liu21st 19 | */ 20 | class ShowRuntimeBehavior extends Behavior { 21 | // 行为参数定义 22 | protected $options = array( 23 | 'SHOW_RUN_TIME' => false, // 运行时间显示 24 | 'SHOW_ADV_TIME' => false, // 显示详细的运行时间 25 | 'SHOW_DB_TIMES' => false, // 显示数据库查询和写入次数 26 | 'SHOW_CACHE_TIMES' => false, // 显示缓存操作次数 27 | 'SHOW_USE_MEM' => false, // 显示内存开销 28 | 'SHOW_LOAD_FILE' => false, // 显示加载文件数 29 | 'SHOW_FUN_TIMES' => false , // 显示函数调用次数 30 | ); 31 | 32 | // 行为扩展的执行入口必须是run 33 | public function run(&$content){ 34 | if(C('SHOW_RUN_TIME')){ 35 | if(false !== strpos($content,'{__NORUNTIME__}')) { 36 | $content = str_replace('{__NORUNTIME__}','',$content); 37 | }else{ 38 | $runtime = $this->showTime(); 39 | if(strpos($content,'{__RUNTIME__}')) 40 | $content = str_replace('{__RUNTIME__}',$runtime,$content); 41 | else 42 | $content .= $runtime; 43 | } 44 | }else{ 45 | $content = str_replace(array('{__NORUNTIME__}','{__RUNTIME__}'),'',$content); 46 | } 47 | } 48 | 49 | /** 50 | * 显示运行时间、数据库操作、缓存次数、内存使用信息 51 | * @access private 52 | * @return string 53 | */ 54 | private function showTime() { 55 | // 显示运行时间 56 | G('beginTime',$GLOBALS['_beginTime']); 57 | G('viewEndTime'); 58 | $showTime = 'Process: '.G('beginTime','viewEndTime').'s '; 59 | if(C('SHOW_ADV_TIME')) { 60 | // 显示详细运行时间 61 | $showTime .= '( Load:'.G('beginTime','loadTime').'s Init:'.G('loadTime','initTime').'s Exec:'.G('initTime','viewStartTime').'s Template:'.G('viewStartTime','viewEndTime').'s )'; 62 | } 63 | if(C('SHOW_DB_TIMES') && class_exists('Db',false) ) { 64 | // 显示数据库操作次数 65 | $showTime .= ' | DB :'.N('db_query').' queries '.N('db_write').' writes '; 66 | } 67 | if(C('SHOW_CACHE_TIMES') && class_exists('Cache',false)) { 68 | // 显示缓存读写次数 69 | $showTime .= ' | Cache :'.N('cache_read').' gets '.N('cache_write').' writes '; 70 | } 71 | if(MEMORY_LIMIT_ON && C('SHOW_USE_MEM')) { 72 | // 显示内存开销 73 | $showTime .= ' | UseMem:'. number_format((memory_get_usage() - $GLOBALS['_startUseMems'])/1024).' kb'; 74 | } 75 | if(C('SHOW_LOAD_FILE')) { 76 | $showTime .= ' | LoadFile:'.count(get_included_files()); 77 | } 78 | if(C('SHOW_FUN_TIMES')) { 79 | $fun = get_defined_functions(); 80 | $showTime .= ' | CallFun:'.count($fun['user']).','.count($fun['internal']); 81 | } 82 | return $showTime; 83 | } 84 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Behavior/TokenBuildBehavior.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | /** 14 | * 系统行为扩展:表单令牌生成 15 | * @category Think 16 | * @package Think 17 | * @subpackage Behavior 18 | * @author liu21st 19 | */ 20 | class TokenBuildBehavior extends Behavior { 21 | // 行为参数定义 22 | protected $options = array( 23 | 'TOKEN_ON' => false, // 开启令牌验证 24 | 'TOKEN_NAME' => '__hash__', // 令牌验证的表单隐藏字段名称 25 | 'TOKEN_TYPE' => 'md5', // 令牌验证哈希规则 26 | 'TOKEN_RESET' => true, // 令牌错误后是否重置 27 | ); 28 | 29 | public function run(&$content){ 30 | if(C('TOKEN_ON')) { 31 | if(strpos($content,'{__TOKEN__}')) { 32 | // 指定表单令牌隐藏域位置 33 | $content = str_replace('{__TOKEN__}',$this->buildToken(),$content); 34 | }elseif(preg_match('/<\/form(\s*)>/is',$content,$match)) { 35 | // 智能生成表单令牌隐藏域 36 | $content = str_replace($match[0],$this->buildToken().$match[0],$content); 37 | } 38 | }else{ 39 | $content = str_replace('{__TOKEN__}','',$content); 40 | } 41 | } 42 | 43 | // 创建表单令牌 44 | private function buildToken() { 45 | $tokenName = C('TOKEN_NAME'); 46 | $tokenType = C('TOKEN_TYPE'); 47 | if(!isset($_SESSION[$tokenName])) { 48 | $_SESSION[$tokenName] = array(); 49 | } 50 | // 标识当前页面唯一性 51 | $tokenKey = md5($_SERVER['REQUEST_URI']); 52 | if(isset($_SESSION[$tokenName][$tokenKey])) {// 相同页面不重复生成session 53 | $tokenValue = $_SESSION[$tokenName][$tokenKey]; 54 | }else{ 55 | $tokenValue = $tokenType(microtime(TRUE)); 56 | $_SESSION[$tokenName][$tokenKey] = $tokenValue; 57 | } 58 | $token = ''; 59 | return $token; 60 | } 61 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Behavior/WriteHtmlCacheBehavior.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | /** 14 | * 系统行为扩展:静态缓存写入 15 | * @category Think 16 | * @package Think 17 | * @subpackage Behavior 18 | * @author liu21st 19 | */ 20 | class WriteHtmlCacheBehavior extends Behavior { 21 | 22 | // 行为扩展的执行入口必须是run 23 | public function run(&$content){ 24 | if(C('HTML_CACHE_ON') && defined('HTML_FILE_NAME')) { 25 | //静态文件写入 26 | // 如果开启HTML功能 检查并重写HTML文件 27 | // 没有模版的操作不生成静态文件 28 | if(!is_dir(dirname(HTML_FILE_NAME))) 29 | mkdir(dirname(HTML_FILE_NAME),0755,true); 30 | if( false === file_put_contents( HTML_FILE_NAME , $content )) 31 | throw_exception(L('_CACHE_WRITE_ERROR_').':'.HTML_FILE_NAME); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Core/Behavior.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP Behavior基础类 14 | * @category Think 15 | * @package Think 16 | * @subpackage Core 17 | * @author liu21st 18 | */ 19 | abstract class Behavior { 20 | 21 | // 行为参数 和配置参数设置相同 22 | protected $options = array(); 23 | 24 | /** 25 | * 架构函数 26 | * @access public 27 | */ 28 | public function __construct() { 29 | if(!empty($this->options)) { 30 | foreach ($this->options as $name=>$val){ 31 | if(NULL !== C($name)) { // 参数已设置 则覆盖行为参数 32 | $this->options[$name] = C($name); 33 | }else{ // 参数未设置 则传入默认值到配置 34 | C($name,$val); 35 | } 36 | } 37 | array_change_key_case($this->options); 38 | } 39 | } 40 | 41 | // 获取行为参数 42 | public function __get($name){ 43 | return $this->options[strtolower($name)]; 44 | } 45 | 46 | /** 47 | * 执行行为 run方法是Behavior唯一的接口 48 | * @access public 49 | * @param mixed $params 行为参数 50 | * @return void 51 | */ 52 | abstract public function run(&$params); 53 | 54 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Core/Cache.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * 缓存管理类 14 | * @category Think 15 | * @package Think 16 | * @subpackage Core 17 | * @author liu21st 18 | */ 19 | class Cache { 20 | 21 | /** 22 | * 操作句柄 23 | * @var string 24 | * @access protected 25 | */ 26 | protected $handler ; 27 | 28 | /** 29 | * 缓存连接参数 30 | * @var integer 31 | * @access protected 32 | */ 33 | protected $options = array(); 34 | 35 | /** 36 | * 连接缓存 37 | * @access public 38 | * @param string $type 缓存类型 39 | * @param array $options 配置数组 40 | * @return object 41 | */ 42 | public function connect($type='',$options=array()) { 43 | if(empty($type)) $type = C('DATA_CACHE_TYPE'); 44 | $type = strtolower(trim($type)); 45 | $class = 'Cache'.ucwords($type); 46 | if(class_exists($class)) 47 | $cache = new $class($options); 48 | else 49 | throw_exception(L('_CACHE_TYPE_INVALID_').':'.$type); 50 | return $cache; 51 | } 52 | 53 | public function __get($name) { 54 | return $this->get($name); 55 | } 56 | 57 | public function __set($name,$value) { 58 | return $this->set($name,$value); 59 | } 60 | 61 | public function __unset($name) { 62 | $this->rm($name); 63 | } 64 | public function setOptions($name,$value) { 65 | $this->options[$name] = $value; 66 | } 67 | 68 | public function getOptions($name) { 69 | return $this->options[$name]; 70 | } 71 | 72 | /** 73 | * 取得缓存类实例 74 | * @static 75 | * @access public 76 | * @return mixed 77 | */ 78 | static function getInstance() { 79 | $param = func_get_args(); 80 | return get_instance_of(__CLASS__,'connect',$param); 81 | } 82 | 83 | /** 84 | * 队列缓存 85 | * @access protected 86 | * @param string $key 队列名 87 | * @return mixed 88 | */ 89 | // 90 | protected function queue($key) { 91 | static $_handler = array( 92 | 'file' => array('F','F'), 93 | 'xcache'=> array('xcache_get','xcache_set'), 94 | 'apc' => array('apc_fetch','apc_store'), 95 | ); 96 | $queue = isset($this->options['queue'])?$this->options['queue']:'file'; 97 | $fun = isset($_handler[$queue])?$_handler[$queue]:$_handler['file']; 98 | $queue_name=isset($this->options['queue_name'])?$this->options['queue_name']:'think_queue'; 99 | $value = $fun[0]($queue_name); 100 | if(!$value) { 101 | $value = array(); 102 | } 103 | // 进列 104 | if(false===array_search($key, $value)) array_push($value,$key); 105 | if(count($value) > $this->options['length']) { 106 | // 出列 107 | $key = array_shift($value); 108 | // 删除缓存 109 | $this->rm($key); 110 | if(APP_DEUBG){ 111 | //调试模式下,记录出列次数 112 | N($queue_name.'_out_times',1,true); 113 | } 114 | } 115 | return $fun[1]($queue_name,$value); 116 | } 117 | 118 | public function __call($method,$args){ 119 | //调用缓存类型自己的方法 120 | if(method_exists($this->handler, $method)){ 121 | return call_user_func_array(array($this->handler,$method), $args); 122 | }else{ 123 | throw_exception(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_')); 124 | return; 125 | } 126 | } 127 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Core/Log.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * 日志处理类 14 | * @category Think 15 | * @package Think 16 | * @subpackage Core 17 | * @author liu21st 18 | */ 19 | class Log { 20 | 21 | // 日志级别 从上到下,由低到高 22 | const EMERG = 'EMERG'; // 严重错误: 导致系统崩溃无法使用 23 | const ALERT = 'ALERT'; // 警戒性错误: 必须被立即修改的错误 24 | const CRIT = 'CRIT'; // 临界值错误: 超过临界值的错误,例如一天24小时,而输入的是25小时这样 25 | const ERR = 'ERR'; // 一般错误: 一般性错误 26 | const WARN = 'WARN'; // 警告性错误: 需要发出警告的错误 27 | const NOTICE = 'NOTIC'; // 通知: 程序可以运行但是还不够完美的错误 28 | const INFO = 'INFO'; // 信息: 程序输出信息 29 | const DEBUG = 'DEBUG'; // 调试: 调试信息 30 | const SQL = 'SQL'; // SQL:SQL语句 注意只在调试模式开启时有效 31 | 32 | // 日志记录方式 33 | const SYSTEM = 0; 34 | const MAIL = 1; 35 | const FILE = 3; 36 | const SAPI = 4; 37 | 38 | // 日志信息 39 | static $log = array(); 40 | 41 | // 日期格式 42 | static $format = '[ c ]'; 43 | 44 | /** 45 | * 记录日志 并且会过滤未经设置的级别 46 | * @static 47 | * @access public 48 | * @param string $message 日志信息 49 | * @param string $level 日志级别 50 | * @param boolean $record 是否强制记录 51 | * @return void 52 | */ 53 | static function record($message,$level=self::ERR,$record=false) { 54 | if($record || false !== strpos(C('LOG_LEVEL'),$level)) { 55 | self::$log[] = "{$level}: {$message}\r\n"; 56 | } 57 | } 58 | 59 | /** 60 | * 日志保存 61 | * @static 62 | * @access public 63 | * @param integer $type 日志记录方式 64 | * @param string $destination 写入目标 65 | * @param string $extra 额外参数 66 | * @return void 67 | */ 68 | static function save($type='',$destination='',$extra='') { 69 | if(empty(self::$log)) return ; 70 | $type = $type?$type:C('LOG_TYPE'); 71 | if(self::FILE == $type) { // 文件方式记录日志信息 72 | if(empty($destination)) 73 | $destination = C('LOG_PATH').date('y_m_d').'.log'; 74 | //检测日志文件大小,超过配置大小则备份日志文件重新生成 75 | if(is_file($destination) && floor(C('LOG_FILE_SIZE')) <= filesize($destination) ) 76 | rename($destination,dirname($destination).'/'.time().'-'.basename($destination)); 77 | }else{ 78 | $destination = $destination?$destination:C('LOG_DEST'); 79 | $extra = $extra?$extra:C('LOG_EXTRA'); 80 | } 81 | $now = date(self::$format); 82 | error_log($now.' '.get_client_ip().' '.$_SERVER['REQUEST_URI']."\r\n".implode('',self::$log)."\r\n", $type,$destination ,$extra); 83 | // 保存后清空日志缓存 84 | self::$log = array(); 85 | //clearstatcache(); 86 | } 87 | 88 | /** 89 | * 日志直接写入 90 | * @static 91 | * @access public 92 | * @param string $message 日志信息 93 | * @param string $level 日志级别 94 | * @param integer $type 日志记录方式 95 | * @param string $destination 写入目标 96 | * @param string $extra 额外参数 97 | * @return void 98 | */ 99 | static function write($message,$level=self::ERR,$type='',$destination='',$extra='') { 100 | $now = date(self::$format); 101 | $type = $type?$type:C('LOG_TYPE'); 102 | if(self::FILE == $type) { // 文件方式记录日志 103 | if(empty($destination)) 104 | $destination = C('LOG_PATH').date('y_m_d').'.log'; 105 | //检测日志文件大小,超过配置大小则备份日志文件重新生成 106 | if(is_file($destination) && floor(C('LOG_FILE_SIZE')) <= filesize($destination) ) 107 | rename($destination,dirname($destination).'/'.time().'-'.basename($destination)); 108 | }else{ 109 | $destination = $destination?$destination:C('LOG_DEST'); 110 | $extra = $extra?$extra:C('LOG_EXTRA'); 111 | } 112 | error_log("{$now} {$level}: {$message}\r\n", $type,$destination,$extra ); 113 | //clearstatcache(); 114 | } 115 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Core/ThinkException.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP系统异常基类 14 | * @category Think 15 | * @package Think 16 | * @subpackage Core 17 | * @author liu21st 18 | */ 19 | class ThinkException extends Exception { 20 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Core/View.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP 视图类 14 | * @category Think 15 | * @package Think 16 | * @subpackage Core 17 | * @author liu21st 18 | */ 19 | class View { 20 | /** 21 | * 模板输出变量 22 | * @var tVar 23 | * @access protected 24 | */ 25 | protected $tVar = array(); 26 | 27 | /** 28 | * 模板主题 29 | * @var theme 30 | * @access protected 31 | */ 32 | protected $theme = ''; 33 | 34 | /** 35 | * 模板变量赋值 36 | * @access public 37 | * @param mixed $name 38 | * @param mixed $value 39 | */ 40 | public function assign($name,$value=''){ 41 | if(is_array($name)) { 42 | $this->tVar = array_merge($this->tVar,$name); 43 | }else { 44 | $this->tVar[$name] = $value; 45 | } 46 | } 47 | 48 | /** 49 | * 取得模板变量的值 50 | * @access public 51 | * @param string $name 52 | * @return mixed 53 | */ 54 | public function get($name=''){ 55 | if('' === $name) { 56 | return $this->tVar; 57 | } 58 | return isset($this->tVar[$name])?$this->tVar[$name]:false; 59 | } 60 | 61 | /** 62 | * 加载模板和页面输出 可以返回输出内容 63 | * @access public 64 | * @param string $templateFile 模板文件名 65 | * @param string $charset 模板输出字符集 66 | * @param string $contentType 输出类型 67 | * @param string $content 模板输出内容 68 | * @param string $prefix 模板缓存前缀 69 | * @return mixed 70 | */ 71 | public function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') { 72 | G('viewStartTime'); 73 | // 视图开始标签 74 | tag('view_begin',$templateFile); 75 | // 解析并获取模板内容 76 | $content = $this->fetch($templateFile,$content,$prefix); 77 | // 输出模板内容 78 | $this->render($content,$charset,$contentType); 79 | // 视图结束标签 80 | tag('view_end'); 81 | } 82 | 83 | /** 84 | * 输出内容文本可以包括Html 85 | * @access private 86 | * @param string $content 输出内容 87 | * @param string $charset 模板输出字符集 88 | * @param string $contentType 输出类型 89 | * @return mixed 90 | */ 91 | private function render($content,$charset='',$contentType=''){ 92 | if(empty($charset)) $charset = C('DEFAULT_CHARSET'); 93 | if(empty($contentType)) $contentType = C('TMPL_CONTENT_TYPE'); 94 | // 网页字符编码 95 | header('Content-Type:'.$contentType.'; charset='.$charset); 96 | header('Cache-control: '.C('HTTP_CACHE_CONTROL')); // 页面缓存控制 97 | header('X-Powered-By:ThinkPHP'); 98 | // 输出模板文件 99 | echo $content; 100 | } 101 | 102 | /** 103 | * 解析和获取模板内容 用于输出 104 | * @access public 105 | * @param string $templateFile 模板文件名 106 | * @param string $content 模板输出内容 107 | * @param string $prefix 模板缓存前缀 108 | * @return string 109 | */ 110 | public function fetch($templateFile='',$content='',$prefix='') { 111 | if(empty($content)) { 112 | $templateFile = $this->parseTemplate($templateFile); 113 | // 模板文件不存在直接返回 114 | if(!is_file($templateFile)) 115 | throw_exception(L('_TEMPLATE_NOT_EXIST_').'['.$templateFile.']'); 116 | } 117 | // 页面缓存 118 | ob_start(); 119 | ob_implicit_flush(0); 120 | if('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { // 使用PHP原生模板 121 | // 模板阵列变量分解成为独立变量 122 | extract($this->tVar, EXTR_OVERWRITE); 123 | // 直接载入PHP模板 124 | empty($content)?include $templateFile:eval('?>'.$content); 125 | }else{ 126 | // 视图解析标签 127 | $params = array('var'=>$this->tVar,'file'=>$templateFile,'content'=>$content,'prefix'=>$prefix); 128 | tag('view_parse',$params); 129 | } 130 | // 获取并清空缓存 131 | $content = ob_get_clean(); 132 | // 内容过滤标签 133 | tag('view_filter',$content); 134 | // 输出模板文件 135 | return $content; 136 | } 137 | 138 | /** 139 | * 自动定位模板文件 140 | * @access protected 141 | * @param string $template 模板文件规则 142 | * @return string 143 | */ 144 | public function parseTemplate($template='') { 145 | if(is_file($template)) { 146 | $group = defined('GROUP_NAME')?GROUP_NAME.'/':''; 147 | $theme = C('DEFAULT_THEME'); 148 | // 获取当前主题的模版路径 149 | if(1==C('APP_GROUP_MODE')){ // 独立分组模式 150 | define('THEME_PATH', dirname(BASE_LIB_PATH).'/'.$group.basename(TMPL_PATH).'/'.$theme); 151 | define('APP_TMPL_PATH',__ROOT__.'/'.APP_NAME.(APP_NAME?'/':'').C('APP_GROUP_PATH').'/'.$group.basename(TMPL_PATH).'/'.$theme); 152 | }else{ 153 | define('THEME_PATH', TMPL_PATH.$group.$theme); 154 | define('APP_TMPL_PATH',__ROOT__.'/'.APP_NAME.(APP_NAME?'/':'').basename(TMPL_PATH).'/'.$group.$theme); 155 | } 156 | return $template; 157 | } 158 | $template = str_replace(':', '/', $template); 159 | // 获取当前主题名称 160 | $theme = $this->getTemplateTheme(); 161 | // 获取当前模版分组 162 | $group = defined('GROUP_NAME')?GROUP_NAME.'/':''; 163 | if(defined('GROUP_NAME') && strpos($template,'@')){ // 跨分组调用模版文件 164 | list($group,$template) = explode('@',$template); 165 | $group .= '/'; 166 | } 167 | // 获取当前主题的模版路径 168 | if(1==C('APP_GROUP_MODE')){ // 独立分组模式 169 | define('THEME_PATH', dirname(BASE_LIB_PATH).'/'.$group.basename(TMPL_PATH).'/'.$theme); 170 | define('APP_TMPL_PATH',__ROOT__.'/'.APP_NAME.(APP_NAME?'/':'').C('APP_GROUP_PATH').'/'.$group.basename(TMPL_PATH).'/'.$theme); 171 | }else{ 172 | define('THEME_PATH', TMPL_PATH.$group.$theme); 173 | define('APP_TMPL_PATH',__ROOT__.'/'.APP_NAME.(APP_NAME?'/':'').basename(TMPL_PATH).'/'.$group.$theme); 174 | } 175 | 176 | // 分析模板文件规则 177 | if('' == $template) { 178 | // 如果模板文件名为空 按照默认规则定位 179 | $template = MODULE_NAME . C('TMPL_FILE_DEPR') . ACTION_NAME; 180 | }elseif(false === strpos($template, '/')){ 181 | $template = MODULE_NAME . C('TMPL_FILE_DEPR') . $template; 182 | } 183 | return THEME_PATH.$template.C('TMPL_TEMPLATE_SUFFIX'); 184 | } 185 | 186 | /** 187 | * 设置当前输出的模板主题 188 | * @access public 189 | * @param mixed $theme 主题名称 190 | * @return View 191 | */ 192 | public function theme($theme){ 193 | $this->theme = $theme; 194 | return $this; 195 | } 196 | 197 | /** 198 | * 获取当前的模板主题 199 | * @access private 200 | * @return string 201 | */ 202 | private function getTemplateTheme() { 203 | if($this->theme) { // 指定模板主题 204 | $theme = $this->theme; 205 | }else{ 206 | /* 获取模板主题名称 */ 207 | $theme = C('DEFAULT_THEME'); 208 | if(C('TMPL_DETECT_THEME')) {// 自动侦测模板主题 209 | $t = C('VAR_TEMPLATE'); 210 | if (isset($_GET[$t])){ 211 | $theme = $_GET[$t]; 212 | }elseif(cookie('think_template')){ 213 | $theme = cookie('think_template'); 214 | } 215 | if(!in_array($theme,explode(',',C('THEME_LIST')))){ 216 | $theme = C('DEFAULT_THEME'); 217 | } 218 | cookie('think_template',$theme,864000); 219 | } 220 | } 221 | define('THEME_NAME', $theme); // 当前模板主题名称 222 | return $theme?$theme . '/':''; 223 | } 224 | 225 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Core/Widget.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP Widget类 抽象类 14 | * @category Think 15 | * @package Think 16 | * @subpackage Core 17 | * @author liu21st 18 | */ 19 | abstract class Widget { 20 | 21 | // 使用的模板引擎 每个Widget可以单独配置不受系统影响 22 | protected $template = ''; 23 | 24 | /** 25 | * 渲染输出 render方法是Widget唯一的接口 26 | * 使用字符串返回 不能有任何输出 27 | * @access public 28 | * @param mixed $data 要渲染的数据 29 | * @return string 30 | */ 31 | abstract public function render($data); 32 | 33 | /** 34 | * 渲染模板输出 供render方法内部调用 35 | * @access public 36 | * @param string $templateFile 模板文件 37 | * @param mixed $var 模板变量 38 | * @return string 39 | */ 40 | protected function renderFile($templateFile='',$var='') { 41 | ob_start(); 42 | ob_implicit_flush(0); 43 | if(!file_exists_case($templateFile)){ 44 | // 自动定位模板文件 45 | $name = substr(get_class($this),0,-6); 46 | $filename = empty($templateFile)?$name:$templateFile; 47 | $templateFile = BASE_LIB_PATH.'Widget/'.$name.'/'.$filename.C('TMPL_TEMPLATE_SUFFIX'); 48 | if(!file_exists_case($templateFile)) 49 | throw_exception(L('_TEMPLATE_NOT_EXIST_').'['.$templateFile.']'); 50 | } 51 | $template = strtolower($this->template?$this->template:(C('TMPL_ENGINE_TYPE')?C('TMPL_ENGINE_TYPE'):'php')); 52 | if('php' == $template) { 53 | // 使用PHP模板 54 | if(!empty($var)) extract($var, EXTR_OVERWRITE); 55 | // 直接载入PHP模板 56 | include $templateFile; 57 | }elseif('think'==$template){ // 采用Think模板引擎 58 | if($this->checkCache($templateFile)) { // 缓存有效 59 | // 分解变量并载入模板缓存 60 | extract($var, EXTR_OVERWRITE); 61 | //载入模版缓存文件 62 | include C('CACHE_PATH').md5($templateFile).C('TMPL_CACHFILE_SUFFIX'); 63 | }else{ 64 | $tpl = Think::instance('ThinkTemplate'); 65 | // 编译并加载模板文件 66 | $tpl->fetch($templateFile,$var); 67 | } 68 | }else{ 69 | $class = 'Template'.ucwords($template); 70 | if(is_file(CORE_PATH.'Driver/Template/'.$class.'.class.php')) { 71 | // 内置驱动 72 | $path = CORE_PATH; 73 | }else{ // 扩展驱动 74 | $path = EXTEND_PATH; 75 | } 76 | require_cache($path.'Driver/Template/'.$class.'.class.php'); 77 | $tpl = new $class; 78 | $tpl->fetch($templateFile,$var); 79 | } 80 | $content = ob_get_clean(); 81 | return $content; 82 | } 83 | 84 | /** 85 | * 检查缓存文件是否有效 86 | * 如果无效则需要重新编译 87 | * @access public 88 | * @param string $tmplTemplateFile 模板文件名 89 | * @return boolen 90 | */ 91 | protected function checkCache($tmplTemplateFile) { 92 | if (!C('TMPL_CACHE_ON')) // 优先对配置设定检测 93 | return false; 94 | $tmplCacheFile = C('CACHE_PATH').md5($tmplTemplateFile).C('TMPL_CACHFILE_SUFFIX'); 95 | if(!is_file($tmplCacheFile)){ 96 | return false; 97 | }elseif (filemtime($tmplTemplateFile) > filemtime($tmplCacheFile)) { 98 | // 模板文件如果有更新则缓存需要更新 99 | return false; 100 | }elseif (C('TMPL_CACHE_TIME') != 0 && time() > filemtime($tmplCacheFile)+C('TMPL_CACHE_TIME')) { 101 | // 缓存是否在有效期 102 | return false; 103 | } 104 | // 缓存有效 105 | return true; 106 | } 107 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Driver/Cache/CacheFile.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | defined('THINK_PATH') or exit(); 13 | /** 14 | * 文件类型缓存类 15 | * @category Think 16 | * @package Think 17 | * @subpackage Driver.Cache 18 | * @author liu21st 19 | */ 20 | class CacheFile extends Cache { 21 | 22 | /** 23 | * 架构函数 24 | * @access public 25 | */ 26 | public function __construct($options=array()) { 27 | if(!empty($options)) { 28 | $this->options = $options; 29 | } 30 | $this->options['temp'] = !empty($options['temp'])? $options['temp'] : C('DATA_CACHE_PATH'); 31 | $this->options['prefix'] = isset($options['prefix'])? $options['prefix'] : C('DATA_CACHE_PREFIX'); 32 | $this->options['expire'] = isset($options['expire'])? $options['expire'] : C('DATA_CACHE_TIME'); 33 | $this->options['length'] = isset($options['length'])? $options['length'] : 0; 34 | if(substr($this->options['temp'], -1) != '/') $this->options['temp'] .= '/'; 35 | $this->init(); 36 | } 37 | 38 | /** 39 | * 初始化检查 40 | * @access private 41 | * @return boolen 42 | */ 43 | private function init() { 44 | // 创建项目缓存目录 45 | if (!is_dir($this->options['temp'])) { 46 | mkdir($this->options['temp']); 47 | } 48 | } 49 | 50 | /** 51 | * 取得变量的存储文件名 52 | * @access private 53 | * @param string $name 缓存变量名 54 | * @return string 55 | */ 56 | private function filename($name) { 57 | $name = md5($name); 58 | if(C('DATA_CACHE_SUBDIR')) { 59 | // 使用子目录 60 | $dir =''; 61 | for($i=0;$ioptions['temp'].$dir)) { 65 | mkdir($this->options['temp'].$dir,0755,true); 66 | } 67 | $filename = $dir.$this->options['prefix'].$name.'.php'; 68 | }else{ 69 | $filename = $this->options['prefix'].$name.'.php'; 70 | } 71 | return $this->options['temp'].$filename; 72 | } 73 | 74 | /** 75 | * 读取缓存 76 | * @access public 77 | * @param string $name 缓存变量名 78 | * @return mixed 79 | */ 80 | public function get($name) { 81 | $filename = $this->filename($name); 82 | if (!is_file($filename)) { 83 | return false; 84 | } 85 | N('cache_read',1); 86 | $content = file_get_contents($filename); 87 | if( false !== $content) { 88 | $expire = (int)substr($content,8, 12); 89 | if($expire != 0 && time() > filemtime($filename) + $expire) { 90 | //缓存过期删除缓存文件 91 | unlink($filename); 92 | return false; 93 | } 94 | if(C('DATA_CACHE_CHECK')) {//开启数据校验 95 | $check = substr($content,20, 32); 96 | $content = substr($content,52, -3); 97 | if($check != md5($content)) {//校验错误 98 | return false; 99 | } 100 | }else { 101 | $content = substr($content,20, -3); 102 | } 103 | if(C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { 104 | //启用数据压缩 105 | $content = gzuncompress($content); 106 | } 107 | $content = unserialize($content); 108 | return $content; 109 | } 110 | else { 111 | return false; 112 | } 113 | } 114 | 115 | /** 116 | * 写入缓存 117 | * @access public 118 | * @param string $name 缓存变量名 119 | * @param mixed $value 存储数据 120 | * @param int $expire 有效时间 0为永久 121 | * @return boolen 122 | */ 123 | public function set($name,$value,$expire=null) { 124 | N('cache_write',1); 125 | if(is_null($expire)) { 126 | $expire = $this->options['expire']; 127 | } 128 | $filename = $this->filename($name); 129 | $data = serialize($value); 130 | if( C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { 131 | //数据压缩 132 | $data = gzcompress($data,3); 133 | } 134 | if(C('DATA_CACHE_CHECK')) {//开启数据校验 135 | $check = md5($data); 136 | }else { 137 | $check = ''; 138 | } 139 | $data = ""; 140 | $result = file_put_contents($filename,$data); 141 | if($result) { 142 | if($this->options['length']>0) { 143 | // 记录缓存队列 144 | $this->queue($name); 145 | } 146 | clearstatcache(); 147 | return true; 148 | }else { 149 | return false; 150 | } 151 | } 152 | 153 | /** 154 | * 删除缓存 155 | * @access public 156 | * @param string $name 缓存变量名 157 | * @return boolen 158 | */ 159 | public function rm($name) { 160 | return unlink($this->filename($name)); 161 | } 162 | 163 | /** 164 | * 清除缓存 165 | * @access public 166 | * @param string $name 缓存变量名 167 | * @return boolen 168 | */ 169 | public function clear() { 170 | $path = $this->options['temp']; 171 | $files = scandir($path); 172 | if($files){ 173 | foreach($files as $file){ 174 | if ($file != '.' && $file != '..' && is_dir($path.$file) ){ 175 | array_map( 'unlink', glob( $path.$file.'/*.*' ) ); 176 | }elseif(is_file($path.$file)){ 177 | unlink( $path . $file ); 178 | } 179 | } 180 | return true; 181 | } 182 | return false; 183 | } 184 | } -------------------------------------------------------------------------------- /ThinkPHP/Lib/Template/TagLib.class.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | /** 13 | * ThinkPHP标签库TagLib解析基类 14 | * @category Think 15 | * @package Think 16 | * @subpackage Template 17 | * @author liu21st 18 | */ 19 | class TagLib { 20 | 21 | /** 22 | * 标签库定义XML文件 23 | * @var string 24 | * @access protected 25 | */ 26 | protected $xml = ''; 27 | protected $tags = array();// 标签定义 28 | /** 29 | * 标签库名称 30 | * @var string 31 | * @access protected 32 | */ 33 | protected $tagLib =''; 34 | 35 | /** 36 | * 标签库标签列表 37 | * @var string 38 | * @access protected 39 | */ 40 | protected $tagList = array(); 41 | 42 | /** 43 | * 标签库分析数组 44 | * @var string 45 | * @access protected 46 | */ 47 | protected $parse = array(); 48 | 49 | /** 50 | * 标签库是否有效 51 | * @var string 52 | * @access protected 53 | */ 54 | protected $valid = false; 55 | 56 | /** 57 | * 当前模板对象 58 | * @var object 59 | * @access protected 60 | */ 61 | protected $tpl; 62 | 63 | protected $comparison = array(' nheq '=>' !== ',' heq '=>' === ',' neq '=>' != ',' eq '=>' == ',' egt '=>' >= ',' gt '=>' > ',' elt '=>' <= ',' lt '=>' < '); 64 | 65 | /** 66 | * 架构函数 67 | * @access public 68 | */ 69 | public function __construct() { 70 | $this->tagLib = strtolower(substr(get_class($this),6)); 71 | $this->tpl = Think::instance('ThinkTemplate'); 72 | } 73 | 74 | /** 75 | * TagLib标签属性分析 返回标签属性数组 76 | * @access public 77 | * @param string $tagStr 标签内容 78 | * @return array 79 | */ 80 | public function parseXmlAttr($attr,$tag) { 81 | //XML解析安全过滤 82 | $attr = str_replace('&','___', $attr); 83 | $xml = ''; 84 | $xml = simplexml_load_string($xml); 85 | if(!$xml) { 86 | throw_exception(L('_XML_TAG_ERROR_').' : '.$attr); 87 | } 88 | $xml = (array)($xml->tag->attributes()); 89 | $array = array_change_key_case($xml['@attributes']); 90 | if($array) { 91 | $attrs = explode(',',$this->tags[strtolower($tag)]['attr']); 92 | if(isset($this->tags[strtolower($tag)]['must'])){ 93 | $must = explode(',',$this->tags[strtolower($tag)]['must']); 94 | }else{ 95 | $must = array(); 96 | } 97 | foreach($attrs as $name) { 98 | if( isset($array[$name])) { 99 | $array[$name] = str_replace('___','&',$array[$name]); 100 | }elseif(false !== array_search($name,$must)){ 101 | throw_exception(L('_PARAM_ERROR_').':'.$name); 102 | } 103 | } 104 | return $array; 105 | } 106 | } 107 | 108 | /** 109 | * 解析条件表达式 110 | * @access public 111 | * @param string $condition 表达式标签内容 112 | * @return array 113 | */ 114 | public function parseCondition($condition) { 115 | $condition = str_ireplace(array_keys($this->comparison),array_values($this->comparison),$condition); 116 | $condition = preg_replace('/\$(\w+):(\w+)\s/is','$\\1->\\2 ',$condition); 117 | switch(strtolower(C('TMPL_VAR_IDENTIFY'))) { 118 | case 'array': // 识别为数组 119 | $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','$\\1["\\2"] ',$condition); 120 | break; 121 | case 'obj': // 识别为对象 122 | $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','$\\1->\\2 ',$condition); 123 | break; 124 | default: // 自动判断数组或对象 只支持二维 125 | $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','(is_array($\\1)?$\\1["\\2"]:$\\1->\\2) ',$condition); 126 | } 127 | if(false !== strpos($condition, '$Think')) 128 | $condition = preg_replace('/(\$Think.*?)\s/ies',"\$this->parseThinkVar('\\1');" , $condition); 129 | return $condition; 130 | } 131 | 132 | /** 133 | * 自动识别构建变量 134 | * @access public 135 | * @param string $name 变量描述 136 | * @return string 137 | */ 138 | public function autoBuildVar($name) { 139 | if('Think.' == substr($name,0,6)){ 140 | // 特殊变量 141 | return $this->parseThinkVar($name); 142 | }elseif(strpos($name,'.')) { 143 | $vars = explode('.',$name); 144 | $var = array_shift($vars); 145 | switch(strtolower(C('TMPL_VAR_IDENTIFY'))) { 146 | case 'array': // 识别为数组 147 | $name = '$'.$var; 148 | foreach ($vars as $key=>$val){ 149 | if(0===strpos($val,'$')) { 150 | $name .= '["{'.$val.'}"]'; 151 | }else{ 152 | $name .= '["'.$val.'"]'; 153 | } 154 | } 155 | break; 156 | case 'obj': // 识别为对象 157 | $name = '$'.$var; 158 | foreach ($vars as $key=>$val) 159 | $name .= '->'.$val; 160 | break; 161 | default: // 自动判断数组或对象 只支持二维 162 | $name = 'is_array($'.$var.')?$'.$var.'["'.$vars[0].'"]:$'.$var.'->'.$vars[0]; 163 | } 164 | }elseif(strpos($name,':')){ 165 | // 额外的对象方式支持 166 | $name = '$'.str_replace(':','->',$name); 167 | }elseif(!defined($name)) { 168 | $name = '$'.$name; 169 | } 170 | return $name; 171 | } 172 | 173 | /** 174 | * 用于标签属性里面的特殊模板变量解析 175 | * 格式 以 Think. 打头的变量属于特殊模板变量 176 | * @access public 177 | * @param string $varStr 变量字符串 178 | * @return string 179 | */ 180 | public function parseThinkVar($varStr){ 181 | $vars = explode('.',$varStr); 182 | $vars[1] = strtoupper(trim($vars[1])); 183 | $parseStr = ''; 184 | if(count($vars)>=3){ 185 | $vars[2] = trim($vars[2]); 186 | switch($vars[1]){ 187 | case 'SERVER': $parseStr = '$_SERVER[\''.$vars[2].'\']';break; 188 | case 'GET': $parseStr = '$_GET[\''.$vars[2].'\']';break; 189 | case 'POST': $parseStr = '$_POST[\''.$vars[2].'\']';break; 190 | case 'COOKIE': 191 | if(isset($vars[3])) { 192 | $parseStr = '$_COOKIE[\''.$vars[2].'\'][\''.$vars[3].'\']'; 193 | }elseif(C('COOKIE_PREFIX')){ 194 | $parseStr = '$_COOKIE[\''.C('COOKIE_PREFIX').$vars[2].'\']'; 195 | }else{ 196 | $parseStr = '$_COOKIE[\''.$vars[2].'\']'; 197 | } 198 | break; 199 | case 'SESSION': 200 | if(isset($vars[3])) { 201 | $parseStr = '$_SESSION[\''.$vars[2].'\'][\''.$vars[3].'\']'; 202 | }elseif(C('SESSION_PREFIX')){ 203 | $parseStr = '$_SESSION[\''.C('SESSION_PREFIX').'\'][\''.$vars[2].'\']'; 204 | }else{ 205 | $parseStr = '$_SESSION[\''.$vars[2].'\']'; 206 | } 207 | break; 208 | case 'ENV': $parseStr = '$_ENV[\''.$vars[2].'\']';break; 209 | case 'REQUEST': $parseStr = '$_REQUEST[\''.$vars[2].'\']';break; 210 | case 'CONST': $parseStr = strtoupper($vars[2]);break; 211 | case 'LANG': $parseStr = 'L("'.$vars[2].'")';break; 212 | case 'CONFIG': $parseStr = 'C("'.$vars[2].'")';break; 213 | } 214 | }else if(count($vars)==2){ 215 | switch($vars[1]){ 216 | case 'NOW': $parseStr = "date('Y-m-d g:i a',time())";break; 217 | case 'VERSION': $parseStr = 'THINK_VERSION';break; 218 | case 'TEMPLATE':$parseStr = 'C("TEMPLATE_NAME")';break; 219 | case 'LDELIM': $parseStr = 'C("TMPL_L_DELIM")';break; 220 | case 'RDELIM': $parseStr = 'C("TMPL_R_DELIM")';break; 221 | default: if(defined($vars[1])) $parseStr = $vars[1]; 222 | } 223 | } 224 | return $parseStr; 225 | } 226 | 227 | // 获取标签定义 228 | public function getTags(){ 229 | return $this->tags; 230 | } 231 | } -------------------------------------------------------------------------------- /ThinkPHP/README.txt: -------------------------------------------------------------------------------- 1 | +------------------------------------------------------------------- 2 | | 感谢您使用ThinkPHP开发框架 ^_^ 3 | +------------------------------------------------------------------- 4 | | 大道至简 开发由我 WE CAN DO IT,JUST THINK 5 | +------------------------------------------------------------------- 6 | | 版本信息:ThinkPHP 3.1.3 Release 2013/5/16 7 | +------------------------------------------------------------------- 8 | | Copyright(c) 2006-2013 http://thinkphp.cn All rights reserved. 9 | +------------------------------------------------------------------- 10 | 11 | [ 简介 ] 12 | ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架, 13 | 遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而 14 | 诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性 15 | 能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在 16 | 社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,众多 17 | 的典型案例确保可以稳定用于商业以及门户级的开发。 18 | 19 | 经过6年的不断积累和重构,3.*版本在框架底层的定制和扩展方面趋于完善, 20 | 使得应用的开发范围和需求适应度更加扩大,能够满足不同程度的开发人员的 21 | 需求。而且引入了全新的CBD(核心+行为+驱动)架构模式,旨在打造DIY框架 22 | 和AOP编程体验,让ThinkPHP能够在不同方面都能快速满足项目和应用的需求, 23 | 并且正式引入SAE、REST和Mongo支持。 24 | 25 | 使用ThinkPHP,你可以更方便和快捷的开发和部署应用。当然不仅仅是企业级 26 | 应用,任何PHP应用开发都可以从ThinkPHP的简单和快速的特性中受益。 27 | ThinkPHP本身具有很多的原创特性,并且倡导大道至简,开发由我的开发理念, 28 | 用最少的代码完成更多的功能,宗旨就是让WEB应用开发更简单、更快速。 29 | 为此ThinkPHP会不断吸收和融入更好的技术以保证其新鲜和活力,提供WEB应 30 | 用开发的最佳实践!经过6年来的不断重构和改进,ThinkPHP达到了一个新的 31 | 阶段,能够满足企业开发中复杂的项目需求,足以达到企业级和门户级的开 32 | 发标准。 33 | 34 | [ 协议 ] 35 | ThinkPHP遵循Apache2开源许可协议发布,意味着你可以免费使用ThinkPHP, 36 | 甚至允许把你的ThinkPHP应用采用商业闭源发布。 37 | 具体参考LICENSE.txt内容 38 | 39 | [ 特性 ] 40 | CBD架构:ThinkPHP3.0版本引入了全新的CBD(核心+行为+驱动)架构模式, 41 | 打造框架底层DIY定制和类AOP编程体验。利用这一新的特性,开发人员可以 42 | 方便地通过模式扩展为自己量身定制一套属于自己或者企业的开发框架。 43 | 编译机制:独创的项目编译机制,有效减少OOP开发中文件加载的性能开销。 44 | 改进后的项目编译机制,可以支持编译文件直接作为入口载入,并且支持常量 45 | 外部载入,利于产品发布。 46 | 47 | 类库导入:采用基于类库包和命名空间的方式导入类库,让类库导入看起来更 48 | 加简单清晰,而且还支持自动加载和别名导入。为了方便项目的跨平台移植, 49 | 系统还可以严格检查加载文件的大小写。 50 | 51 | URL和路由:系统支持普通模式、PATHINFO模式、REWRITE模式和兼容模式的 52 | URL方式,支持不同的服务器和运行模式的部署,配合URL路由功能,让你随心 53 | 所欲的构建需要的URL地址和进行SEO优化工作。支持灵活的规则路由和正则路 54 | 由,以及路由重定向支持,带给开发人员更方便灵活的URL优化体验。 55 | 调试模式:框架提供的调试模式可以方便用于开发过程的不同阶段,包括开发、 56 | 测试和演示等任何需要的情况,不同的应用模式可以配置独立的项目配置文件。 57 | 只是小小的性能牺牲就能满足调试开发过程中的日志和分析需要,并确保将来的 58 | 部署顺利,一旦切换到部署模式则可以迅速提升性能。 59 | 60 | ORM :简洁轻巧的ORM实现,配合简单的CURD以及AR模式,让开发效率无处不在。 61 | 62 | 数据库:支持包括Mysql、Sqlite、Pgsql、Oracle、SqlServer、Mongo等数据库, 63 | 并且内置分布式数据库和读写分离功能支持。系统支持多数据库连接和动态切换 64 | 机制,犹如企业开发的一把利刃,跨数据库应用和分布式支持从此无忧。 65 | 66 | 查询语言:内建丰富的查询机制,包括组合查询、快捷查询、复合查询、区间 67 | 查询、统计查询、定位查询、多表查询、子查询、动态查询和原生查询,让你的 68 | 数据查询简洁高效。 69 | 70 | 动态模型:无需创建任何对应的模型类,轻松完成CURD操作,支持多种模型之间 71 | 的动态切换,让你领略数据操作的无比畅快和最佳体验。 72 | 73 | 扩展模型:提供了丰富的扩展模型,包括:支持序列化字段、文本字段、只读字 74 | 段、延迟写入、乐观锁、数据分表等高级特性的高级模型;可以轻松动态地创建 75 | 数据库视图的视图模型;支持关联操作的关联模型;支持Mongo数据库的Mongo模 76 | 型等等,都可以方便的使用。 77 | 78 | 模块分组:不用担心大项目的分工协调和部署问题,分组帮你解决跨项目的难题, 79 | 还可以支持对分组的二级域名部署支持。 80 | 81 | 模板引擎:系统内建了一款卓越的基于XML的编译型模板引擎,支持两种类型的 82 | 模板标签,融合了Smarty和JSP标签库的思想,并内置布局模板功能和标签库扩展 83 | 支持。通过驱动还可以支持Smarty、EaseTemplate、TemplateLite、Smart等其他第 84 | 三方模板引擎。 85 | 86 | AJAX支持:内置和客户端无关的AJAX数据返回方法,支持JSON、XML和EVAL类型 87 | 返回客户端,而且可以扩展返回数据格式,系统不绑定任何AJAX类库,可随意使 88 | 用自己熟悉的AJAX类库进行操作。 89 | 90 | 云引擎支持:提供了新浪SAE平台和百度BAE平台的强力支持,具备“横跨性”和“平滑性”,支持本地化 91 | 开发和调试以及部署切换,让你轻松过渡,打造全新的开发体验。 92 | 93 | RESTFul支持:REST模式提供了RESTFul支持,为你打造全新的URL设计和访问体验, 94 | 同时为接口应用提供了支持。 95 | 96 | 多语言支持:系统支持语言包功能,项目和分组都可以有单独的语言包,并且可以 97 | 自动检测浏览器语言自动载入对应的语言包。 98 | 99 | 模式扩展:除了标准模式外,还提供了AMF、PHPRpc、Lite、Thin和Cli模式扩展支 100 | 持,针对不同级别的应用开发提供最佳核心框架,还可以自定义模式扩展。 101 | 102 | 自动验证和完成:自动完成表单数据的验证和过滤,新版新增了IP验证和有效期验 103 | 证等更多的验证方式,配合自动完成可以生成安全的数据对象。 104 | 105 | 字段类型检测:系统会自动缓存字段信息和字段类型,支持非法字段过滤和字段类 106 | 型强制转换,确保数据写入和查询更安全。 107 | 108 | 缓存机制:系统支持包括文件方式、APC、Db、Memcache、Shmop、Sqlite、Redis、 109 | Eaccelerator和Xcache在内的动态数据缓存类型,以及可定制的静态缓存规则,并 110 | 提供了快捷方法进行存取操作。 111 | 112 | 扩展机制:系统支持包括模式扩展、行为扩展、类库扩展、驱动扩展、模型扩展、 113 | 控制器扩展、Widget扩展在内的强大灵活的扩展机制,让你不再受限于核心的不足 114 | 和无所适从,随心DIY自己的框架和扩展应用,满足企业开发中更加复杂的项目需求。 115 | 116 | [ 要求 ] 117 | ThinkPHP3.1需要PHP5.2.0以上版本支持,可以运行在任何系统环境下面。 118 | 119 | [ 安装 ] 120 | ThinkPHP无需安装,下载ThinkPHP核心包或者完整版之后,把解压后的目录拷贝到 121 | 你的WEB服务器或者WEB目录即可。 122 | 123 | [ 鸣谢 ] 124 | 特别要鸣谢ThinkPHP团队和所有关注和支持ThinkPHP的用户。 125 | 126 | [ 支持 ] 127 | 更多内容和支持请访问ThinkPHP官方网站http://thinkphp.cn/。 -------------------------------------------------------------------------------- /ThinkPHP/ThinkPHP.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | // ThinkPHP 入口文件 13 | // 记录开始运行时间 14 | $GLOBALS['_beginTime'] = microtime(TRUE); 15 | // 记录内存初始使用 16 | define('MEMORY_LIMIT_ON',function_exists('memory_get_usage')); 17 | if(MEMORY_LIMIT_ON) $GLOBALS['_startUseMems'] = memory_get_usage(); 18 | // 系统目录定义 19 | defined('THINK_PATH') or define('THINK_PATH', dirname(__FILE__).'/'); 20 | defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']).'/'); 21 | defined('APP_DEBUG') or define('APP_DEBUG',false); // 是否调试模式 22 | if(defined('ENGINE_NAME')) { 23 | defined('ENGINE_PATH') or define('ENGINE_PATH',THINK_PATH.'Extend/Engine/'); 24 | require ENGINE_PATH.strtolower(ENGINE_NAME).'.php'; 25 | }else{ 26 | defined('RUNTIME_PATH') or define('RUNTIME_PATH',APP_PATH.'Runtime/'); 27 | $runtime = defined('MODE_NAME')?'~'.strtolower(MODE_NAME).'_runtime.php':'~runtime.php'; 28 | defined('RUNTIME_FILE') or define('RUNTIME_FILE',RUNTIME_PATH.$runtime); 29 | if(!APP_DEBUG && is_file(RUNTIME_FILE)) { 30 | // 部署模式直接载入运行缓存 31 | require RUNTIME_FILE; 32 | }else{ 33 | // 加载运行时文件 34 | require THINK_PATH.'Common/runtime.php'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ThinkPHP/Tpl/default_index.tpl: -------------------------------------------------------------------------------- 1 | show('

:)

欢迎使用 ThinkPHP

','utf-8'); 6 | } 7 | } -------------------------------------------------------------------------------- /ThinkPHP/Tpl/dispatch_jump.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 跳转提示 6 | 16 | 17 | 18 |
19 | 20 |

:)

21 |

22 | 23 |

:(

24 |

25 |
26 |

27 |

28 | 页面自动 跳转 等待时间: 29 |

30 |
31 | 43 | 44 | -------------------------------------------------------------------------------- /ThinkPHP/Tpl/page_trace.tpl: -------------------------------------------------------------------------------- 1 |
2 | 24 | 25 |
26 |
27 | -------------------------------------------------------------------------------- /ThinkPHP/Tpl/think_exception.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 系统发生错误 5 | 21 | 22 | 23 |
24 |

:(

25 |

26 |
27 | 28 |
29 |
30 |

错误位置

31 |
32 |
33 |

FILE:  LINE:

34 |
35 |
36 | 37 | 38 |
39 |
40 |

TRACE

41 |
42 |
43 |

44 |
45 |
46 | 47 |
48 |
49 | 52 | 53 | -------------------------------------------------------------------------------- /ThinkPHP/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/ThinkPHP/logo.png -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/favicon.ico -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | prompt(1)'', ''email'': ''ya@xx.com'', ''password'': ''admin'', ''sub'': ''submit'', ''sex'': ''''} : URL ( scheme = http, netloc = w, path = /try/vul_lab/form.php, params = {}, query = )", "field": "username"}'), 92 | (123, '6a1411f02eff98a', 'xss', '{"xss_type": "GET", "detail": "GET : URL ( scheme = http, netloc = w, path = /try/vul_lab/xss.php, params = {''a'': ''test'', ''b'': u''xxx''}, query = a=test&b=xxx%3Cimg%20src%3D1%20onerror%3Dprompt%281%29%3E)", "param": "b"}'), 93 | (124, '6a1411f02eff98a', 'sqli', '{"sqli_type": "MySQL Error Based", "detail": "GET : URL ( scheme = http, netloc = w, path = /try/vul_lab/sqli.php, params = {''x'': ''1'', ''id'': \\"1''\\"}, query = x=1&id=1%27)", "param": "id"}'); 94 | 95 | -- -------------------------------------------------------- 96 | 97 | -- 98 | -- 表的结构 `pb_user` 99 | -- 100 | 101 | CREATE TABLE IF NOT EXISTS `pb_user` ( 102 | `uid` int(11) NOT NULL AUTO_INCREMENT, 103 | `name` varchar(60) COLLATE utf8_bin NOT NULL, 104 | `email` varchar(120) COLLATE utf8_bin NOT NULL, 105 | `password` varchar(32) COLLATE utf8_bin NOT NULL, 106 | `key` int(11) NOT NULL, 107 | `ip` varchar(32) COLLATE utf8_bin NOT NULL, 108 | `user_hash` varchar(15) COLLATE utf8_bin NOT NULL, 109 | PRIMARY KEY (`uid`), 110 | UNIQUE KEY `name` (`name`) 111 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=2 ; 112 | 113 | -- 114 | -- 转存表中的数据 `pb_user` 115 | -- 116 | 117 | INSERT INTO `pb_user` (`uid`, `name`, `email`, `password`, `key`, `ip`, `user_hash`) VALUES 118 | (1, 'Yaseng', 'yaseng@uauc.net', '350cdd6f9854da616acb21', 1390034392, '', '68bc1fd5938fc77'); 119 | 120 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 121 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 122 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 123 | -------------------------------------------------------------------------------- /playweb/Common/common.php: -------------------------------------------------------------------------------- 1 | ~`+=,.;:/?|'; 16 | $str = ''; 17 | for ( $i = 0; $i < $length; $i++ ) 18 | { 19 | $str .= $chars[ mt_rand(0, strlen($chars) - 1) ]; 20 | } 21 | return $str; 22 | 23 | } 24 | /** 25 | * @desc 获取唯一的hash值 26 | * @return string 长度为 15 的 唯一 hash 值 27 | **/ 28 | function get_hash(){ 29 | 30 | return substr(md5(rand_str().time()),0,15); 31 | 32 | } 33 | 34 | function str_encode($str,$key){ 35 | 36 | $strlength=strlen($str); 37 | $baselength=strlen($key); 38 | $ret=""; 39 | for($i=0;$i<$strlength;$i++){ 40 | 41 | $ret.=chr((ord($str[$i])+ord($key[$i % $baselength]))%256); 42 | 43 | } 44 | 45 | return base64_encode($ret); 46 | } 47 | 48 | function str_decode($str,$key){ 49 | 50 | $str=base64_decode($str); 51 | $strlength=strlen($str); 52 | $baselength=strlen($key); 53 | $ret=""; 54 | for($i=0;$i<$strlength;$i++){ 55 | 56 | $ret.=chr((ord($str[$i])-ord($key[$i % $baselength]))%256); 57 | 58 | } 59 | 60 | return $ret; 61 | } 62 | 63 | ?> -------------------------------------------------------------------------------- /playweb/Common/functions.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /playweb/Conf/config.php: -------------------------------------------------------------------------------- 1 | 0, 4 | 'URL_HTML_SUFFIX'=>'', 5 | 6 | 'TMPL_PARSE_STRING' =>array( 7 | '__STATIC__'=>__ROOT__.'/PlayWeb/Static', 8 | '__JS__'=>__ROOT__.'/PlayWeb/Static/js', 9 | '__CSS__'=>__ROOT__.'/PlayWeb/Static/css', 10 | '__IMAGE__'=>__ROOT__.'/PlayWeb/Static/image', 11 | '__EDITOR__'=>__ROOT__.'/PlayWeb/Static/kindeditor' 12 | ), 13 | 14 | 'DB_TYPE' => 'mysql', // 数据库类型 15 | 'DB_HOST' => 'localhost', // 服务器地址 16 | 'DB_NAME' => 'playweb', // 数据库名 17 | 'DB_USER' => 'root', // 用户名 18 | 'DB_PWD' => '', // 密码 19 | 'DB_PORT' => 3306, // 端口 20 | 'DB_PREFIX' => 'pb_', // 数据库表前缀 21 | 22 | 'URL_CASE_INSENSITIVE'=>true, // url不区分大小写 23 | 'COOKIE_PREFIX' => 'cv_', //cookie 前缀 24 | 'LOG_RECORD' => true, // 开启日志记录 25 | 'LOG_LEVEL' =>'EMERG,ALERT,CRIT,ERR,SQL', // 只记录EMERG ALERT CRIT ERR 错误 26 | ); 27 | 28 | return $arr_config; -------------------------------------------------------------------------------- /playweb/Lib/Action/CommonAction.class.php: -------------------------------------------------------------------------------- 1 | _g['type']=array(1=>"sql注入",2=>"xss",3=>"代码执行"); 16 | $this->_g['level']=array(1=>array("name"=>"高危","style"=>"important"),2=>array("name"=>"中危","style"=>"warning"),3=>array("name"=>"低危","style"=>"info")); 17 | $this->_check_user(); 18 | $this->assign('_g',$this->_g); 19 | } 20 | 21 | private function _check_user(){ 22 | 23 | $uid=intval(cookie("uid")); 24 | $token=cookie("uhash"); 25 | if($uid){ 26 | 27 | $this->_g['user']=D("User")->check($uid, $hash); 28 | } 29 | 30 | 31 | } 32 | /** 33 | *@name 前台消息提示函数 34 | *@param text 提示内容 35 | **/ 36 | public function msg(){ 37 | 38 | 39 | } 40 | /** 41 | * @name 查询权限 42 | * @param id 权限表对应的id 默认为0 极为登陆权限 43 | * @param text 44 | * @param url 45 | **/ 46 | public function _check_priv($id=0,$text="",$url=""){ 47 | 48 | if($id==0 && !$this->_g['user']){ 49 | 50 | 51 | 52 | 53 | $text="请先登陆"; 54 | $url=U('User/login'); 55 | $this->error($text,$url); 56 | 57 | 58 | } 59 | 60 | 61 | return ; 62 | } 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | } -------------------------------------------------------------------------------- /playweb/Lib/Action/IndexAction.class.php: -------------------------------------------------------------------------------- 1 | _check_priv(); 12 | 13 | 14 | 15 | $this->display(); 16 | 17 | 18 | } 19 | } -------------------------------------------------------------------------------- /playweb/Lib/Action/NodeAction.class.php: -------------------------------------------------------------------------------- 1 | node_key); 25 | 26 | 27 | } 28 | 29 | 30 | /** 31 | * @desc 所有节点列表 32 | **/ 33 | function listing(){ 34 | 35 | 36 | $this->_check_priv(); 37 | $nodes=M("Node")->where(array("status"=> 1,"user_hash"=> $this->_g['user']['user_hash']))->select(); 38 | $online_nodes=array(); 39 | foreach ($nodes as $node) { 40 | 41 | /* if(time() - $node['time'] < 10 ){ //断线延时 10秒 42 | 43 | $online_nodes[]=$node; 44 | 45 | } 46 | */ 47 | $online_nodes[]=$node; 48 | } 49 | 50 | $this->ajaxReturn($online_nodes); 51 | 52 | 53 | } 54 | 55 | /** 56 | * @desc Node 节点 57 | * @return hash 节点的hash 58 | **/ 59 | public function login(){ 60 | 61 | $os=$this->_get("os"); 62 | $user_hash=$this->_get("user_hash"); 63 | $ip=get_client_ip(); 64 | $node_hash=get_hash(); 65 | M("Node")->add(array("ip"=> $ip, "os"=> $os,"user_hash"=> $user_hash,"node_hash"=> $node_hash,"time"=>time(),"status"=> 1)); 66 | echo $node_hash; 67 | 68 | 69 | } 70 | 71 | /** 72 | * @desc 获取扫描项目 73 | * @param $hash 节点hash 74 | * @return 75 | **/ 76 | public function get_project(){ 77 | 78 | $nodes=M("Node")->select(); 79 | $online_nodes=array(); 80 | foreach ($nodes as $node) { 81 | 82 | /* if(time() - $node['time'] < 10 ){ //断线延时 10秒 83 | 84 | $online_nodes[]=$node; 85 | 86 | } 87 | */ 88 | $online_nodes[]=$node; 89 | } 90 | 91 | $this->ajaxReturn($online_nodes); 92 | 93 | } 94 | 95 | 96 | 97 | /** 98 | * @desc 获取任务 99 | * @param $nodeid 100 | **/ 101 | public function get_task(){ 102 | 103 | $node_hash="68bc1fd5938fc77"; 104 | //$node_hash=$this->_post("node_hash"); 105 | $project=M("project")->where(array("status"=>0))->find(); 106 | // M("project")->where(array("id"=>$project['id']))->save(array("status"=>1)); 107 | if($project){ 108 | 109 | $project=array_merge($project,unserialize($project['setting'])); 110 | unset($project['setting']); 111 | //dump($project); 112 | 113 | //$this->node_key=$project['project_hash'].$node_hash; 114 | 115 | $this->node_return($project); 116 | } 117 | 118 | 119 | 120 | } 121 | 122 | function update(){ 123 | 124 | $node_hash=$this->_get("node_hash"); 125 | // M("Node")->where(array("node_hash"=> $node_hash))->save(array("time"=> time())); 126 | 127 | } 128 | 129 | /* 130 | * 扫描报告 131 | */ 132 | function report(){ 133 | 134 | 135 | $post=$this->_post(); 136 | 137 | //file_put_contents("1.txt", str_decode($post['content'], $this->node_key)."\r\n",FILE_APPEND); 138 | $report=(array)json_decode(str_decode($post['content'], $this->node_key)); 139 | $arr_type=array("sys_info","sqli","xss"); 140 | if(in_array($report['type'], $arr_type)){ 141 | 142 | M("report")->add($report); 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 | ?> -------------------------------------------------------------------------------- /playweb/Lib/Action/ProjectAction.class.php: -------------------------------------------------------------------------------- 1 | _check_priv(); 20 | $ret['target']=$this->_post("target"); 21 | $arr_setting=array("web_ports"=>"80,8080","start_time"=>time()); 22 | $ret['setting']=serialize($arr_setting); 23 | $ret['project_hash']=get_hash(); 24 | //异常处理 !!! 25 | $ret['id']=M("project")->add($ret); 26 | if($ret['id']){ 27 | 28 | $this->ajaxReturn($ret); 29 | 30 | } 31 | 32 | 33 | 34 | } 35 | 36 | function test(){ 37 | 38 | $post=$this->_post(); 39 | $ret['target']=$post["target"]; 40 | $module=""; 41 | foreach ($post['moudle'] as $k=>$v){ 42 | 43 | $module.=$k.","; 44 | } 45 | $arr_setting=array("module"=>substr($module,0,strlen($module)-1),"start_time"=>time()); 46 | $arr_setting=array_merge($post['setting'],$arr_setting); 47 | $ret['setting']=serialize($arr_setting); 48 | $ret['project_hash']=get_hash(); 49 | //异常处理 !!! 50 | $ret['id']=M("project")->add($ret); 51 | if($ret['id']){ 52 | 53 | $this->ajaxReturn($ret); 54 | 55 | } 56 | 57 | } 58 | 59 | 60 | 61 | } 62 | 63 | ?> -------------------------------------------------------------------------------- /playweb/Lib/Action/ReportAction.class.php: -------------------------------------------------------------------------------- 1 | _get("id")); 20 | $project=M("project")->find($id); 21 | $this->assign("project",$project); 22 | $this->display(); 23 | 24 | 25 | } 26 | 27 | 28 | public function update(){ 29 | 30 | $project_hash=$this->_get("project_hash"); 31 | $last_count=intval($this->_get("last_count")); 32 | $count=M("report")->where(array("project_hash"=>$project_hash))->count(); 33 | if($count > $last_count){ 34 | 35 | $data=M("report")->order('id desc')->limit($count-$last_count)->select(); 36 | $reports=array(); 37 | foreach ($data as $item ){ 38 | 39 | $arr=json_decode($item['content']); 40 | $report['type']=$item['type']; 41 | if($report['type'] == "sys_info"){ 42 | 43 | $report['port']=$arr->port; 44 | $report['service']=$arr->service; 45 | 46 | } 47 | 48 | $report['info']=""; 49 | unset($arr->port); 50 | unset($arr->service); 51 | foreach ($arr as $key=>$info){ 52 | 53 | $report['info'].=$key."=".htmlspecialchars($info)." "; 54 | 55 | } 56 | 57 | $reports[]=$report; 58 | 59 | } 60 | 61 | // dump($reports); 62 | $this->ajaxReturn(($reports)); 63 | 64 | } 65 | 66 | 67 | 68 | } 69 | 70 | 71 | } 72 | 73 | 74 | 75 | 76 | ?> -------------------------------------------------------------------------------- /playweb/Lib/Action/UserAction.class.php: -------------------------------------------------------------------------------- 1 | _check_priv(); //是否登陆 16 | 17 | dump($this->_g['user']); 18 | 19 | } 20 | /** 21 | * @desc 注册 22 | **/ 23 | public function reg(){ 24 | 25 | $this->display(); 26 | 27 | } 28 | 29 | public function on_reg(){ 30 | 31 | if($this->_post("password") == $this->_post("password2")){ 32 | 33 | $ret=D("user")->add($_post("username"),$_post("password"),$_post("email")); 34 | } 35 | 36 | 37 | } 38 | 39 | 40 | 41 | /** 42 | * @desc 登陆 43 | **/ 44 | public function login(){ 45 | 46 | 47 | $time=time(); 48 | 49 | $this->display(); 50 | 51 | } 52 | 53 | public function on_login(){ 54 | 55 | $ret=D("User")->login($this->_post('username'),$this->_post('password')); 56 | $this->ajaxReturn($ret); 57 | 58 | } 59 | public function logout(){ 60 | 61 | setcookie("cv_uid", "", time() - 3600, "/", "", FALSE, TRUE); 62 | setcookie("cv_uhash", "", time() - 3600, "/", "", FALSE, TRUE); 63 | $this->success("退出成功",U('index/index')); 64 | 65 | } 66 | 67 | 68 | 69 | } 70 | 71 | ?> -------------------------------------------------------------------------------- /playweb/Lib/Model/NodeModel.class.php: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /playweb/Lib/Model/UserModel.class.php: -------------------------------------------------------------------------------- 1 | where(array("uid"=> $uid))->find(); 53 | // return (make_hash($user) == $hash ) ? $user : null; 54 | return $user; 55 | 56 | 57 | } 58 | 59 | 60 | function add($username,$password,$email){ 61 | 62 | 63 | 64 | } 65 | 66 | 67 | function login($username,$password){ 68 | 69 | $ret['status']=0; 70 | $ret['info']="用户名或密码错误"; 71 | $user=$this->where(array("name"=> $username))->find(); 72 | if($user){ 73 | 74 | if($this->checkmd5($password,$user['key']) == $user['password']){ 75 | 76 | $ret['status']=1; 77 | $ret['info']="登陆成功"; 78 | setcookie("cv_uid", $user['uid'], time()+60 * 60 * 24 * 10, "/", "", FALSE, TRUE); 79 | setcookie("cv_uhash",$this->make_hash($user), time()+60 * 60 * 24 * 10, "/", "", FALSE, TRUE); 80 | 81 | } 82 | } 83 | return $ret; 84 | 85 | 86 | } 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | } 96 | 97 | ?> -------------------------------------------------------------------------------- /playweb/Runtime/Cache/2d57c07f14e7f6e0bbf4108f98365878.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 用户注册 -PlayWeb 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 44 | 45 | 46 | 47 | 48 | 51 | 52 | 53 | 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 | 131 | 132 | -------------------------------------------------------------------------------- /playweb/Runtime/Cache/3ef5e2f17b29f37d0c954b34f6e3fa90.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <?php echo ($project['target']); ?> -扫描报告 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 48 |
49 | 50 | 57 | 156 |
157 |
158 |
159 | 162 |
164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 198 | 199 | 200 |
目标
进度20%
设置
操作 182 | 184 |    185 | 187 |    188 | 189 | 191 |    192 | 193 | 195 | 196 | 197 |
201 |
202 |
203 |
204 |
表格
205 |
206 | 207 |
208 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 |
等级类型详细信息
222 | 223 | 224 | 225 |
226 | 229 |
231 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 257 | 258 |
端口服务详细信息
259 |
260 |
261 | 262 | 263 | 264 | 265 |
266 | 294 | 295 | -------------------------------------------------------------------------------- /playweb/Runtime/Cache/477cb8eed6d581df4cc21aa850723f4a.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 用户登陆 -PlayWeb 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 44 | 45 | 46 | 47 | 48 | 51 | 52 | 53 | 76 |
77 | 78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | 89 |
90 |
91 |
92 | 93 |
94 | 95 |
96 | 124 | 125 | -------------------------------------------------------------------------------- /playweb/Runtime/Cache/9885ecc411f90bec36756701bd64bb4a.php: -------------------------------------------------------------------------------- 1 |

:)

欢迎使用 ThinkPHP

-------------------------------------------------------------------------------- /playweb/Runtime/Cache/a8f553bbee87836198ce5a1333d1f6c2.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 跳转提示 6 | 16 | 17 | 18 |
19 |

:)

20 |

21 | 22 |

:(

23 |

24 |

25 |

26 | 页面自动 跳转 等待时间: 27 |

28 |
29 | 41 | 42 | -------------------------------------------------------------------------------- /playweb/Tpl/Public/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | title 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 48 |
49 | 50 |
51 | 79 | 80 | -------------------------------------------------------------------------------- /playweb/Tpl/Public/dialog.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaseng/playweb/1fce7261df8c1082988c5c24157df22b5d9ffc86/playweb/Tpl/Public/dialog.html -------------------------------------------------------------------------------- /playweb/Tpl/Report/view.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {$project['target']} -扫描报告 4 | 5 | 6 | 13 | 112 |
113 |
114 |
115 | 118 |
120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 154 | 155 | 156 |
目标{$project['target']}
进度20%
设置
操作 138 | 140 |    141 | 143 |    144 | 145 | 147 |    148 | 149 | 151 | 152 | 153 |
157 |
158 |
159 |
160 |
表格
161 |
162 | 163 |
164 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 |
等级类型详细信息
178 | 179 | 180 | 181 |
182 | 185 |
187 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 213 | 214 |
端口服务详细信息
215 |
216 |
217 | 218 | 219 | 220 |
-------------------------------------------------------------------------------- /playweb/Tpl/User/Login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 用户登陆 -PlayWeb 4 | 5 | 6 | 31 | 32 | 33 | 34 | 35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | 46 |
47 |
48 |
49 | 50 |
51 |
-------------------------------------------------------------------------------- /playweb/Tpl/User/Reg.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 用户注册 -PlayWeb 4 | 5 | 6 | 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 |
--------------------------------------------------------------------------------