├── .htaccess
├── .travis.yml
├── README
├── config.php
├── controller
├── home.php
├── home_c.php
└── index.html
├── index.php
├── library
├── cache.php
├── controller.php
├── db.php
├── index.html
├── input.php
├── load.php
├── router.php
└── session.php
├── model
└── index.html
├── routes.php
└── view
├── footer.php
├── header.php
└── home.php
/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine on
2 | RewriteCond %{REQUEST_FILENAME} !-f
3 | RewriteCond %{REQUEST_FILENAME} !-d
4 | RewriteRule ^(.*)$ /index.php/$1 [L]
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.4
5 | - 5.5
6 | - 5.6
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | /* Whats this?? */
2 | its a No Framework PHP MVC.
3 | a really really small framework... believe it or not!
4 | Only 20 kb unzipped
5 |
6 | /* How to Create Routes? */
7 | Define your route on routes.php file, and add route by calling,
8 | // load::l('router')->add('/[uri path]','[template file name]');
9 |
10 | load::l('router')->add('/','home');
11 | load::l('router')->add('/home/(.+)/([0-9]+)','home'); //Regex Route
12 |
13 | /* How to Create Controller? */
14 | Save your controller file at controller dir, ex: /controller/home_c.php
15 | the class name will be Class Home_c{}, and then extend it with Controller abstract class
16 |
17 | Class Home_c extends Controller
18 | {
19 | public function __construct()
20 | {
21 | //Getting Regex Arguments from URL Segments if exists (optional)
22 | $reg = load::l('router')->reg_segments;
23 |
24 | //Set Template Variable
25 | $this->setOutput(array('hello'=>"Hello World!"));
26 | }
27 | }
28 | //!important!
29 | Controller must be load directly on your view file
30 |
31 | /* How to Create your Template/View? */
32 | Save your view file at view dir, ex: /view/home.php
33 |
34 | //Optional (you may want a simple static template)
35 | On your view file, load the CONTROLLER AT THE VERY TOP OF CODE LINE, by calling
36 | extract(load::c('[controller name]')->getOutput());
37 | and extract it if you have output variables from the controller.
38 |
39 | You may load other view/template by calling
40 | // load::v('[template file name]');
41 |
42 | home.php <<<
43 | 1. getOutput()); //Load and extract controller variables ?>
44 | 2.
45 | 3.
46 | 4.
47 | 5.
48 |
49 | /* How to Create Library/Model? */
50 | Basically you only need to create a reguler class base on your model/library file,
51 | its the same like controller does.
52 | ex : /model/home_m.php , and the class name will be, Class Home_m {}
53 | ex : /library/mylib_l.php , and the class name will be, Class mylib_l {}
54 |
55 | You may load the library or model anytime anywhere by calling
56 | // load::m('[model name]')->[method name]
57 | // load::l('[library name]')->[method name]
58 |
59 | /* Wrappers */
60 | load::c('[controller name]',[arguments array optional]);
61 | load::m('[model name]',[arguments array optional]);
62 | load::v('[view name]',[arguments array optional]);
63 | load::l('[library name]',[arguments array optional]);
64 |
--------------------------------------------------------------------------------
/config.php:
--------------------------------------------------------------------------------
1 | reg_segments;
8 |
9 | $this->setVars(array('hello'=>"Hello World!"));
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/controller/home_c.php:
--------------------------------------------------------------------------------
1 | reg_segments;
8 |
9 | $this->setOutput(array('hello'=>"Hello World!"));
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/controller/index.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kh411d/no-framework-php/545265b95e56ba9f723ecfc149b077cec315d360/controller/index.html
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | add('/',DEFAULT_ROUTE);
18 |
19 | //Include Other Routes
20 | include "routes.php";
21 |
22 | //Ready get set .... Go!
23 | load::l('router')->run();
--------------------------------------------------------------------------------
/library/cache.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/library/controller.php:
--------------------------------------------------------------------------------
1 | vars[$idx]) ? $this->vars[$idx] : $this->vars;
10 |
11 | return $this->vars;
12 | }
13 |
14 | protected function setOutput($key,$value = NULL)
15 | {
16 | if(is_array(func_get_arg(0))){
17 | foreach(func_get_arg(0) as $key => $value)$this->vars[$key] = $value;
18 | }else{
19 | $this->vars[$key] = $value;
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/library/db.php:
--------------------------------------------------------------------------------
1 | dbh = new PDO(DB_ENGINE.':'.'dbname='.DB_NAME.';host='.DB_HOST, DB_USER, DB_PASSWORD);
15 | $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
16 | } catch (PDOException $e) {
17 | echo 'Connection failed: ' . $e->getMessage();
18 | }
19 | }
20 |
21 | public function query($sql,$params = NULL,$return = PDO::FETCH_OBJ)
22 | {
23 | try
24 | {
25 | $sth = $this->dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
26 | $sth->execute($params);
27 | return $sth->fetchAll($return);
28 | }
29 | catch (PDOException $e)
30 | {
31 | echo $e->getMessage()."-".$sql;
32 | return false;
33 | }
34 | }
35 |
36 | public function get_row($sql,$params = NULL,$return = PDO::FETCH_OBJ)
37 | {
38 | try
39 | {
40 | $sth = $this->dbh->prepare($sql);
41 | $sth->execute($params);
42 | return $sth->fetch($return);
43 | }
44 | catch (PDOException $e)
45 | {
46 | echo $e->getMessage()."-".$sql;
47 | return false;
48 | }
49 | }
50 |
51 | function get_var($sql,$params = NULL)
52 | {
53 | try
54 | {
55 | $sth = $this->dbh->prepare($sql);
56 | $sth->execute($params);
57 | return $sth->fetchcolumn();
58 | }
59 | catch (PDOException $e)
60 | {
61 | echo $e->getMessage()."-".$sql;
62 | return false;
63 | }
64 | }
65 |
66 |
67 | public function insert($table, $data) {
68 | $fields = array_keys($data);
69 | $param_fields = array();
70 | foreach ( $fields as $field ) {
71 | $param_fields[] = ":".addslashes($field);
72 | }
73 | //echo $sql;
74 | $sql = "INSERT INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $param_fields ) . ")";
75 |
76 | try
77 | {
78 | $sth = $this->dbh->prepare($sql);
79 | $sth->execute($data);
80 | return $this->dbh->lastInsertId();
81 | }
82 | catch (PDOException $e)
83 | {
84 | echo $e->getMessage()."-".$sql;
85 | return false;
86 | }
87 | }
88 |
89 |
90 | public function update($table, $data, $where) {
91 | if ( !is_array( $where ) )
92 | return false;
93 |
94 | $bits = $wheres = array();
95 | foreach ( (array) array_keys($data) as $field ) {
96 | $form = ":".addslashes($field);
97 | $bits[] = "`$field` = {$form}";
98 | }
99 |
100 | foreach ( (array) array_keys($where) as $field ) {
101 | $form = ":".addslashes($field);
102 | $wheres[] = "`$field` = {$form}";
103 | }
104 |
105 | $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
106 |
107 | try
108 | {
109 | $sth = $this->dbh->prepare($sql);
110 | $sth->execute($data);
111 | return $this->dbh->rowCount();
112 | }
113 | catch (PDOException $e)
114 | {
115 | echo $e->getMessage()."-".$sql;
116 | return false;
117 | }
118 | }
119 |
120 | public function start_transact()
121 | {
122 | $this->dbh->beginTransaction();
123 | }
124 |
125 | public function end_transact()
126 | {
127 | $this->dbh->commit();
128 | }
129 |
130 | public function rollback_transact()
131 | {
132 | $this->dbh->rollBack();
133 | }
134 |
135 |
136 | }
137 |
138 |
--------------------------------------------------------------------------------
/library/index.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kh411d/no-framework-php/545265b95e56ba9f723ecfc149b077cec315d360/library/index.html
--------------------------------------------------------------------------------
/library/input.php:
--------------------------------------------------------------------------------
1 | '[removed]',
18 | 'document.write' => '[removed]',
19 | '.parentNode' => '[removed]',
20 | '.innerHTML' => '[removed]',
21 | 'window.location' => '[removed]',
22 | '-moz-binding' => '[removed]',
23 | '' => '-->',
25 | ' '<![CDATA['
26 | );
27 | /* never allowed, regex replacement */
28 | protected $never_allowed_regex = array(
29 | "javascript\s*:" => '[removed]',
30 | "expression\s*(\(|&\#40;)" => '[removed]', // CSS and IE
31 | "vbscript\s*:" => '[removed]', // IE, surprise!
32 | "Redirect\s+302" => '[removed]'
33 | );
34 |
35 | public function __construct()
36 | {
37 | $this->sanitize();
38 | }
39 |
40 | protected function sanitize()
41 | {
42 | if(isset($_GET))
43 | $_GET = $this->clean_input_data($_GET);
44 | if(isset($_POST))
45 | $_POST = $this->clean_input_data($_POST);
46 |
47 | //You will need to use html_entity_decode() for all cookie after sanitizing input
48 | //if(isset($_COOKIE))
49 | //$_COOKIE = $this->clean_input_data($_COOKIE);
50 |
51 | }
52 |
53 | public function get($key)
54 | {
55 | return $_GET[$key];
56 | }
57 |
58 | public function post($key)
59 | {
60 | return $_POST[$key];
61 | }
62 |
63 | public function clean_input_data($str)
64 | {
65 | if (is_array($str))
66 | {
67 | $new_array = array();
68 | foreach ($str as $key => $val)
69 | {
70 | $new_array[$this->clean_input_keys($key)] = $this->clean_input_data($val);
71 | }
72 | return $new_array;
73 | }
74 |
75 | // We strip slashes if magic quotes is on to keep things consistent
76 | if (get_magic_quotes_gpc())
77 | {
78 | $str = stripslashes($str);
79 | }
80 |
81 | // Should we filter the input data?
82 | if ($this->use_xss_clean === TRUE)
83 | {
84 | $str = $this->xss_clean($str);
85 | }
86 |
87 | // Standardize newlines
88 | if (strpos($str, "\r") !== FALSE)
89 | {
90 | $str = str_replace(array("\r\n", "\r"), "\n", $str);
91 | }
92 |
93 |
94 | /*if(!get_magic_quotes_gpc()) {
95 | $str = addslashes($str);
96 | }*/
97 | $str = htmlspecialchars($str,ENT_QUOTES);
98 |
99 | return $str;
100 | }
101 |
102 | protected function clean_input_keys($str)
103 | {
104 | if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
105 | {
106 | die('Disallowed Key Characters.');
107 | }
108 |
109 | return $str;
110 | }
111 |
112 | function xss_clean($str, $is_image = FALSE)
113 | {
114 | if (is_array($str))
115 | {
116 | while (list($key) = each($str))
117 | {
118 | $str[$key] = $this->xss_clean($str[$key]);
119 | }
120 |
121 | return $str;
122 | }
123 |
124 | $str = preg_replace('|\&([a-z\_0-9]+)\=([a-z\_0-9]+)|i', $this->xss_hash()."\\1=\\2", $str);
125 | $str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str);
126 | $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);
127 | $str = str_replace($this->xss_hash(), '&', $str);
128 | $str = rawurldecode($str);
129 | $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
130 | $str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_html_entity_decode_callback'), $str);
131 | $str = $this->_remove_invisible_characters($str);
132 |
133 | if (strpos($str, "\t") !== FALSE)
134 | {
135 | $str = str_replace("\t", ' ', $str);
136 | }
137 |
138 | $converted_string = $str;
139 |
140 | foreach ($this->never_allowed_str as $key => $val)
141 | {
142 | $str = str_replace($key, $val, $str);
143 | }
144 |
145 | foreach ($this->never_allowed_regex as $key => $val)
146 | {
147 | $str = preg_replace("#".$key."#i", $val, $str);
148 | }
149 |
150 | if ($is_image === TRUE)
151 | {
152 | $str = preg_replace('/<\?(php)/i', "<?\\1", $str);
153 | }
154 | else
155 | {
156 | $str = str_replace(array('', '?'.'>'), array('<?', '?>'), $str);
157 | }
158 |
159 | $words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window');
160 | foreach ($words as $word)
161 | {
162 | $temp = '';
163 |
164 | for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++)
165 | {
166 | $temp .= substr($word, $i, 1)."\s*";
167 | }
168 |
169 | $str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
170 | }
171 |
172 | do
173 | {
174 | $original = $str;
175 |
176 | if (preg_match("/]*?)(>|$)#si", array($this, '_js_link_removal'), $str);
179 | }
180 |
181 | if (preg_match("/
]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str);
184 | }
185 |
186 | if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str))
187 | {
188 | $str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);
189 | }
190 | }
191 | while($original != $str);
192 |
193 | unset($original);
194 |
195 | $event_handlers = array('[^a-z_\-]on\w*','xmlns');
196 |
197 | if ($is_image === TRUE)
198 | {
199 | unset($event_handlers[array_search('xmlns', $event_handlers)]);
200 | }
201 |
202 | $str = preg_replace("#<([^><]+?)(".implode('|', $event_handlers).")(\s*=\s*[^><]*)([><]*)#i", "<\\1\\4", $str);
203 |
204 | $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';
205 | $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
206 |
207 | $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str);
208 |
209 | foreach ($this->never_allowed_str as $key => $val)
210 | {
211 | $str = str_replace($key, $val, $str);
212 | }
213 |
214 | foreach ($this->never_allowed_regex as $key => $val)
215 | {
216 | $str = preg_replace("#".$key."#i", $val, $str);
217 | }
218 |
219 | if ($is_image === TRUE)
220 | {
221 | if ($str == $converted_string)
222 | {
223 | return TRUE;
224 | }
225 | else
226 | {
227 | return FALSE;
228 | }
229 | }
230 | return $str;
231 | }
232 |
233 | function xss_hash()
234 | {
235 | if ($this->xss_hash == '')
236 | {
237 | if (phpversion() >= 4.2)
238 | mt_srand();
239 | else
240 | mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff);
241 |
242 | $this->xss_hash = md5(time() + mt_rand(0, 1999999999));
243 | }
244 |
245 | return $this->xss_hash;
246 | }
247 |
248 | function _remove_invisible_characters($str)
249 | {
250 | static $non_displayables;
251 |
252 | if ( ! isset($non_displayables))
253 | {
254 | // every control character except newline (dec 10), carriage return (dec 13), and horizontal tab (dec 09),
255 | $non_displayables = array(
256 | '/%0[0-8bcef]/', // url encoded 00-08, 11, 12, 14, 15
257 | '/%1[0-9a-f]/', // url encoded 16-31
258 | '/[\x00-\x08]/', // 00-08
259 | '/\x0b/', '/\x0c/', // 11, 12
260 | '/[\x0e-\x1f]/' // 14-31
261 | );
262 | }
263 |
264 | do
265 | {
266 | $cleaned = $str;
267 | $str = preg_replace($non_displayables, '', $str);
268 | }
269 | while ($cleaned != $str);
270 |
271 | return $str;
272 | }
273 |
274 | function _compact_exploded_words($matches)
275 | {
276 | return preg_replace('/\s+/s', '', $matches[1]).$matches[2];
277 | }
278 |
279 | function _sanitize_naughty_html($matches)
280 | {
281 | // encode opening brace
282 | $str = '<'.$matches[1].$matches[2].$matches[3];
283 |
284 | // encode captured opening or closing brace to prevent recursive vectors
285 | $str .= str_replace(array('>', '<'), array('>', '<'), $matches[4]);
286 |
287 | return $str;
288 | }
289 |
290 | function _js_link_removal($match)
291 | {
292 | $attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));
293 | return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|