volomike / faster Goto Github PK
View Code? Open in Web Editor NEWA Minimalist, Zero-Config PHP MVC Framework
A Minimalist, Zero-Config PHP MVC Framework
I hate to break compatibility, but we're early in the game here. See, more people are used to using a configuration file that's named config.php instead of site.php. So, I'm going to be changing that.
I found one really strange web host where the base URL was not properly discovered. This was due to a wacky configuration where the $_SERVER['DOCUMENT_ROOT'] parameter was not returning the proper result.
This led me to discover a really bad couple of lines in index.php, which I should never have done. These are the only lines that deal with DOCUMENT_ROOT. The line looks like this:
$sPath = str_replace('\\', '/', substr(dirname(__FILE__), strlen($_SERVER['DOCUMENT_ROOT'])));
As you can see, that's kind of a blind line -- super risky!
The fix is to replace that line with this:
$sPath = str_replace('index.php','',$_SERVER['SCRIPT_NAME']);
It is in the baseurl() and the getPath() functions.
The sample model that's provided has a pretty significant SQL injection vulnerability:
https://github.com/volomike/Faster/blob/master/app/_models/Sample/Test.php#L28
That variable must be bound as a parameter, not just included inline in the query...
Vladimir Nikolic asked if we could have another Faster_Request class method called getRequest(). It would use $_GET or $_POST, depending on whether the server received a POST request or not. Note we don't want to use $_REQUEST because it has a problem, as spelled out here:
http://devlog.info/2010/02/04/why-php-request-array-is-dangerous/
So, in a nutshell, the class method would sort of look like:
See if ($_POST). If so, then process with getPostedVar(). Otherwise, process with getVar().
I think this is a valid, very small thing to add, and which may help speed up development. I wouldn't personally use getRequest() except for testing purposes, and that's why it might help speed up development (because it speeds up testing).
Currently when we try to access the action, group, URL params, base file path, or base URL path, we are making a computation each time. Instead, we need to utilize a session variable that caches these items on subsequent lookups.
I'm hoping you'll see this. It's not a feature or a bug, but I wanted a pleasant way to inform you followers of the Faster framework to my recent blog post about it, and to gather more feedback.
I received a request where one wanted to manually override the autodetection of the Base Path and/or Base URL and pull from config.php instead. This will have an effect on baseurl(), base(), and getPath(). This option needs to run super fast and be completely optional as an override.
I'll work this into the 1.037 release.
Need to add "$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);" after the SQLite PDO connection is established. Otherwise, we'll get meaningless non-object errors when the SQL is not correct during an $st = $PDO->prepare($sSQL) call.
You're using some Javascript, jQuery, or some third-party component which performs a GET request over AJAX and sends parameters. It's the equivalent of putting ?a=1 or something on the end of a URL, as far as the Apache web server is concerned. But each time you run it, your page controller never gets called and instead it defaults back to Default/cDefault.php.
As a shortcut, I'm going to be adding HEADER and FOOTER constants so that at the top of your view pages you can do:
<? require_once(HEADER); ?>
and at the bottom do:
<? require_once(FOOTER); ?>
These in turn will map to your app/_views folder as HEADER.php and FOOTER.php automatically. You can use these constants or avoid them. You can also edit the top of index.php to change them to a different name or path.
I'm going to be adding these class methods to Faster_Request:
getVar($sKey)
getPostedVar($sKey)
getParam($sKey)
getServerVar($sKey)
Currently the Faster_Request has the plural of these which return an array, but someone may wish to use $this->request->getVar('fldFirstName') for instance to get items individually without array conversion.
Hi, here is some idea to use
in index.php line 1130
public function logger($log) {
if ($log != '') {
$fh = fopen($this->base() . '/log/log.log', "a");
if (is_array($log)) {
fwrite($fh, date('Y-m-d H:i:s') . "\n");
foreach ($log as $key => $value) {
fwrite($fh, $value . "\n");
}
fwrite($fh, "\n\n");
} else {
fwrite($fh, date('Y-m-d H:i:s') . "\n" . $log . "\n\n");
}
fclose($fh);
}
}
make /log/log.log directory and file in root of framework and call it $this->core->logger('whatever'); and now is easy to make any log ;)
i hope that i help someone ;)
In Faster, the index.php is not only the front controller, but also the framework bootstrap. I was asked if someone should edit the index.php file for things like global constants or functions they want to easily make available to all the page controllers. I recommended against editing the index.php because then it makes it hard to debug if this gets out of hand, where you want to figure out what was a bug in the framework versus your editing of the index.php.
The user requested that we have an "app/extra.php" file added to the framework that gets called with an include() before "// handle our front controller task". Therefore, we can add global constants and helper functions.
I thought it was a good idea, and will include it in a future release -- definitely.
Need to revisit these functions;
writePersistentCookie()
writeEncryptedPersistentCookie()
It was foolish to hard-code the date to 365 days out. This should have had an optional $nDays parameter on the end of the parameter list, set to 365 by default.
I found a problem where, if I made a hyperlink with ".php" on the end (a common mistake), the system would route to the default path instead of a special path that the user wanted with the hyperlink. The reason was because the $this->request->polishAction() would return the ".php" and then the $this->request->getGroup() and $this->request->getAction() routines would tack on an extra ".php" on the end. The fix was to edit the polishAction() class method and remove any ".php" that it finds as far as an ending extension.
Without fixing this, very strange, hard to find bugs occur where form posts keep going back to the default page (app/_controllers/Default/cDefault.php). As well, AJAX calls on
Of course, this ultimately is user error, but there's no harm in us heading that off by fixing the polishAction() class method with this string check and replacement.
I need to search/replace in index.php for...
'mysql:dbname=%s;host=%s;port=$sPort'
...and replace with...
'mysql:dbname=%s;host=%s;port=%s'
There's a bug in 1.0369 where the index.php references a short_open_tags ini setting, but it is supposed to be short_open_tag.
The getNewID has a recursive call but fails to use $this.
Currently in the app folder, we have a config.php. However, imagine someone who takes Faster to make a software product, and he wants an install script to create the config.php. Two problems occur:
chmod -R 0755 app
or chmod -R 0777 app
. That's a problem because it opens up security issues that people might forget to undo. A better solution would be to move config.php into an app/_config path, and then a customer merely has to make app/_config writable, rather than app.Because the config file is part of the framework, the config folder should probably be _config for consistency reasons. Besides, in some text editors, this sorts this folder to the top, which people kind of prefer.
Therefore, I suggest a change where we move config.php to app/_config, and then we revise index.php so that it does a file_exists check and moves on without it if necessary.
For some reason, I had a glaring bug where the cookie prefix was putting the underscore before the prefix, not after it. It still worked, but you'd see the cookie label like:
_prefixlabel
instead of:
prefix_label
There's a major bug where we can't do $this->request->* from the Models. It's a one-liner easy fix. I need to fix it in the Faster_Model class.
This is a concept I'm playing around with. Feel free to add your commentary.
One of the most painful things a developer has to do is make a paginated recordset and a pagination control. Faster doesn't include that because we like the idea of using best-of-breed components and reducing the time required to learn the core framework. We want to keep the core limited. However, it seems suitable that Faster evolve to include a plugins framework just as cool as the one with WordPress, and which lets you install and uninstall functionality like a pagination API.
In a paginated feature, there are really 2 points of frustration:
To implement this in Faster, it appears that we would want to have a "_plugins" folder under the "app" folder. In that folder, one would create new directories for their plugins, just like WordPress has. Then, we need like a plugin initializer script, which we could call init.php. This would load our callback functions into the Faster API at critical event junctures. As Faster runs through its typical bootstrap -> front controller -> page controller -> model -> database -> model -> page controller -> view var injection -> view display path, it would have event junctures we could intercept, receiving all critical data so that we can modify it before it moves to the next juncture. Our init.php script of our plugin could load those callback functions into a Faster master plugin table.
We can handle in our page controller the parsing of the URL to get the page number. Now we need our LIMIT clause parameters of Offset and Limit. Our Pagination plugin can have a callback when the page controller loads, instantiating a $Paginator class object. We can then use it to give us our Offset and Limit. The other thing we need is to render a typical pagination control in HTML. So, since $Paginator class object is loaded in memory and available to our page controller, we can call $Paginator, pass it some of these parameters, and it can render the HTML for us, which we can then use to display on the page.
As for the event table, we can cache it in a session array variable. No database necessary. It would load the plugin callbacks into the event table and cache it for the remainder of a user session. That way, unless a plugin folder's md5 checksum doesn't change, it keeps this cached and doesn't have to keep reloading that table all the time.
As the event junctures occur, they can then call the callbacks with call_user_func_array() and pass it the relevant data one usually needs at these junctures. (We can define this further in a Plugin API Codex.)
Now one thing we need to think about here is that someone may use Faster for like their product catalog application, and may want to offer a plugin API feature for it. (That's a common thing in product catalogs.) Therefore, we offer this in the above spec, but we're autoloading those plugins. We need a setting in the app/config.php to not autoload, and to require that one amend a file like app/_plugins/installed.php on what plugins are installed or not. That way, one's admin page of their product catalog application can install and uninstall plugins with ease.
Thoughts?
The dispatchRoute routine is not properly assigning 404 on bad paths. Instead, it's defaulting to the homepage.
The PDO quote() function leaves much to be desired. We're told to use mysql_real_escape_string(), but that requires a connection to the database to be passed to it for some strange reason. By adding escapeValue() to the Faster_Data class, we can mimic this behavior. The function would be:
* Escapes a value for use in a SQL statement.
*
* @param string The variable to encode.
* @return string The encoded variable ready for use in a SQL statement.
*/
public function escapeValue($s) {
if(!empty($s)) {
return str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $s);
}
return $s;
}
Even though Faster is to remain minimalist, this is such a commonly desired thing that it seems suitable to add it to the framework in the appropriate class, which would be the Faster_Data class.
In the bootstrap/front controller (aka "index.php"), I'm hard-coding the session timeouts to one hour. However, people may want longer session timeouts, such as a guy who uses session variables for shopping cart items that he wants to cache for an entire day. So, I'm going to change this to use an app/config.php option like SESSION_TIMEOUT_MINUTES and set it to 60 (for 1 hour) by default.
The framework loads from command line, but returns HTML back as if one went to / in the URL. Instead, I need to do it similarly to how Kohana does it, where I can do...
php index.php --path=/sample-group/sample-action
...and it automatically routes me to app/_controllers/SampleGroup/cSampleAction.php to begin the code execution.
The current getNewID() strategy in the Faster_Data class has a limit of around 46 million. You can do your own math, but I came up with around 46 to 47 million as I analyzed that routine. By using a Trigesimal with a dash, however, we can use those same 8 digits (including the dash position) and get a number range of 21 billion. I document this here:
http://voloreport.com/the-case-against-mysql-autoincrement-columns
Some sample outputs of this would be like:
JRS-81MH
6VJ-MDH2
F8Q-6Z06
BXL-PCLN
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.