url rewrite and google robots txt - php

I use php slim framework, with url rewrite here is my host real file structure:
like most framework all rewrite to index.php
/.htaccess
/assets
/index.php
/phpinfo.php
/robots.txt
/usr
/controller
/model
...
and here is my router
$app->get('/backstage', $authenticate(), function () use ($uri, $app) {...});
$app->get('/api', $authenticate(), function () use ($uri, $app) {...});
$app->get('/', function () use ($uri, $app) {...});
$app->get('/article', function () use ($uri, $app) {...});
How to disable /backstage, /api in my route, and real file path /phpin.php, /usr,
And accept /, /article in router?
I'm confusing should I fill router path or real file path? because real file path there is not exist /article
and this is I tried
User-agent: *
Disallow: /backstage/
Disallow: /phpinfo.php

First (assuming you use apache), you need to make sure your .htaccess file correctly points requests to your router file.
--- begin .htaccess snippet ---
<IfModule mod_rewrite.c>
RewriteEngine On
## direct all requests to Slim router
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ slim-router.php [QSA,L]
</IfModule>
--- end .htaccess snippet ---
I may not be understanding your question properly, but to disable a route, simply comment out the line in slim-router.php that adds the route.
Adding entries to robots.txt will not prevent browsers from reaching a URI, it only exists to ask search engine bots (i.e., GoogleBot) to not index that particular URI. See robotstxt.org and the robots.txt entry on Wikipedia.
To direct a route to an existing file, you can use the \Slim\View class (see the \Slim\View documentation).
This example expects a file named templates/article.php to exist, which is the file that will output the content for the /article route.
Using the \Slim\View class, you can also send data to the template file, which I have demonstrated below as well. This is only a basic example, see the documentation for more complex usage.
//--- begin slim-router.php ---
$app = new \Slim\Slim();
$defview = new \Slim\View();
$defview->setTemplatesDirectory(realpath(__DIR__).'/templates');
$app->get(
'/article',
function () use ($app) {
global $defview;
//show the contents of 'templates/article.php', passing optional data to the template file:
$app->view($defview)->display(
'article.php',
array(
'data_one'=>'one',
'data_two'=>2,
'three'=>'3',
)
);
}
);
//--- end slim-router.php ---

Related

Slim Framework routes returns not found except "get" named ones

I use: slim-skeleton (Mr. Rob Allen's scaffold provided on github)
Under /projects grouped routes, only "get" method routes work without any problem but with rest of all return page not found error. Also these routes have auth middleware + cors middleware (Cors Middleware taken from Slim Framework's v3 Documentation).
Here is my ../src/routes.php file:
use Slim\Http\Request;
use Slim\Http\Response;
// Routes
// Administration
$app->group('/admin', function() use ($app) {
// Dashboard
$app->get('/dashboard', 'App\Controllers\Admin\Dashboard:index');
// Projects and images management
$app->group('/projects', function() use ($app){
// Projects Actions
$app->get('/list', 'App\Controllers\Admin\ProjectManagement:index');
$app->post('/add', 'App\Controllers\Admin\ProjectManagement:add'); # NOT WORKING
$app->get('/id/{id}', 'App\Controllers\Admin\ProjectManagement:find');
$app->put('/edit/{id}', 'App\Controllers\Admin\ProjectManagement:edit'); # NOT WORKING
$app->delete('/remove/{id}', 'App\Controllers\Admin\ProjectManagement:remove'); # NOT WORKING
// Project Images Actions
$app->get('/{pid}/images', 'App\Controllers\Admin\ProjectImageManagement:attachments');
$app->post('/{pid}/images/attach', 'App\Controllers\Admin\ProjectImageManagement:attach');
// Project's Image management
$app->get('/{pid}/images/id/{id}', 'App\Controllers\Admin\ProjectImageManagement:find');
$app->put('/{pid}/images/edit/{id}', 'App\Controllers\Admin\ProjectImageManagement:edit');
$app->delete('/{pid}/images/remove/{id}', 'App\Controllers\Admin\ProjectImageManagement:removeImage');
/**
* Project's Image Sort Order
*
* Additional Info:
*
* GET /{pid}/images Retrieves current sort order beforehand
*
*/
$app->put('/{pid}/images/order/{id}/resort', 'App\Controllers\Admin\ProjectImageManagement:sortOrder');
});
// Page management
$app->group('/pages', function() use ($app) {
// About Page
$app->get('/about/content', 'App\Controllers\Admin\PageManagement:aboutPage');
$app->put('/about/content/update', 'App\Controllers\Admin\PageManagement:updateAbout');
// Contact Page
$app->get('/contact/content', 'App\Controllers\Admin\PageManagement:contactPage');
$app->put('/contact/content/update', 'App\Controllers\Admin\PageManagement:updateContact');
});
// Settings
$app->group('/settings', function() use ($app) {
// Account
$app->get('/account/details', 'App\Controllers\Admin\Settings:accountDetails');
$app->post('/account/details/apply', 'App\Controllers\Admin\Settings::applyAccountSettingChanges');
});
})->add($auth);
// Auth
$app->get('/auth/point', 'App\Controllers\AuthController:checkPoint');
$app->post('/auth/login','App\Controllers\AuthController:login');
$app->get('/auth/logout', 'App\Controllers\AuthController:logout');
// Guest
$app->get('/about', 'App\Controllers\Guest\PageContents:about');
$app->get('/contact', 'App\Controllers\Guest\PageContents:contact');
$app->get('/works', 'App\Controllers\Guest\ProjectExplorer:projects');
And here is my .htaccess under /public directory:
<IfModule mod_rewrite.c>
RewriteEngine On
# Some hosts may require you to use the `RewriteBase` directive.
# Determine the RewriteBase automatically and set it as environment v
ariable.
# If you are using Apache aliases to do mass virtual hosting or
installed the
# project in a subdirectory, the base path will be prepended to allow proper
# resolution of the index.php file and to redirect to the correct URI. It will
# work in environments without path prefix as well, providing a safe, one-size
# fits all solution. But as you do not need it in this case, you can comment
# the following 2 lines to eliminate the overhead.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# If the above doesn't work you might need to set the `RewriteBase` directive manually, it should be the
# absolute physical path to the directory that contains this htaccess file.
# RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</IfModule>
I also added Allow from all, but it results in same way. But if i have doing something wrong why all other routes created outside of "/projects" work well. For instance, Auth related routes work well.
I know that, I have to see "Method Not Allowed" warning instead of seeing not found. Where am i doing something wrong? Any help would be very appreciated.
EDIT:
$app->map(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], '/{routes:.+}', function($req, $res) {
$handler = $this->notFoundHandler; // handle using the default Slim page not found handler
return $handler($req, $res);
});
I forgot this one. This mapping hides/exchanges method not allowed page => not found handler. It seems to me as an application based error. Sorry for my carelessness...
My suggestion is to add a root for the group you added
$app->group('/admin', function(){};
Under this you should add
$this->get('', function(){/*-----activities----*/});
And try to use $this while using the groups
Explanation:
when you are using $app you are referring to slim object.
when you are using $this inside your $app->group(){} then you are referring to grouped object which will be responsible for grouping the statements.
So, basically when you use $app inside the group then you make it useless because your slim-app is looking for it on above layer of the code(ie. outside the group). and you are not using group object($this in this case) to declare routes so eventually they are getting declared but not addressed properly.
$app->map(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], '/{routes:.+}', function($req, $res) {
$handler = $this->notFoundHandler; // handle using the default Slim page not found handler
return $handler($req, $res);
});
I forgot this one. This mapping hides/exchanges method not allowed page => not found handler. It seems to me as an application based error. Sorry for my carelessness...
But in my opinion notFoundHandler is not the right choice for this. A custom error message has to be raised for this situation like 405 Method Not Allowed - (notFoundHandler returns 404)
Not sure if this is the case, but if you need to change $app->get or $app->post to $this->get or $this->post if you group the routes.

Host a Slim microsite in a subdirectory

Is there a nice and supported way to define routes like this:
$app->get('/', function (Request $request, Response $response) {
});
$app->get('/hello/{name}', function (Request $request, Response $response) {
});
... and get them work as expected no matter the location of the index.php routing file?
E.g. if DOCUMENT_ROOT is C:\Projects\Playground (http://playground.example.com) and my router file is located at C:\Projects\Playground\PHP\Slim\foo\bar\index.php (http://playground.example.com/PHP/Slim/foo/bar) I'd like http://playground.example.com/PHP/Slim/foo/bar/hello/world! to match '/hello/{name}'.
(Every other file belonging to Slim would be somewhere else, let's say C:\Libraries\Slim, and should be irrelevant to this question.)
With nice and supported I mean not this:
$uri_prefix = complex_function_to_calculate_it($_SERVER['DOCUMENT_ROOT'], __DIR__);
$app->get($uri_prefix . '/hello/{name}', function (Request $request, Response $response) {
});
Slim 3 uses nikic/fast-route but I couldn't find any hint.
Besides creating .htaccess file in the subdirectory:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
you need to either configure web server or slim:
Solution 1 (configure apache):
On debian 9 open the following file:
/etc/apache2/apache2.conf
Once opened, modify
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
into
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
and then restart the apache to apply the changes:
systemctl restart apache2
Solution 2 (configure slim):
Attach this:
// Activating routes in a subfolder
$container['environment'] = function () {
$scriptName = $_SERVER['SCRIPT_NAME'];
$_SERVER['SCRIPT_NAME'] = dirname(dirname($scriptName)) . '/' . basename($scriptName);
return new Slim\Http\Environment($_SERVER);
};
Note that you'll need to use subdir name in the routes, e.g. /subdir/ for home, or some specific route: /subdir/auth/signup
Oh well... If it isn't supported out of the box, I guess it's better to just not complicate it too much and make it a parameter:
define('ROUTE_PREFIX', '/PHP/Slim/foo/bar');
$app->get(ROUTE_PREFIX . '/hello/{name}', function (Request $request, Response $response) {
});
After all, writing generic code that calculates it dynamically under all circumstances is too much of a burden, esp. when you can have endless factors like symlinks or Apache aliases.
The parameter should of course be defined with the rest of your site settings (either src/settings.php if you use Slim Skeleton, .env if you use phpdotenv... whatever).
You could nest all of your routes inside of a wrapper group in Slim, for which the path pattern is determined based on the $_SERVER variable:
$app = Slim\Factory\AppFactory::create();
$app->group(dirname($_SERVER['SCRIPT_NAME']), function($subdirectory) {
$subdirectory->group('/api/v1', $function($api) {
// define routes as usual, e.g...
$api->get('/foo/{foo:[0-9]+}', function($req, $res) {
// ...
});
});
});
A little pre-processing of the $_SERVER['SCRIPT_NAME'] variable lets you do other things -- detect that your API is nested inside a directory named API and don't append another API to the route pattern, for example.

Laravel 4.2 filter access to uploaded files

I want to route to filter access to files in upploads folder.
Route::get('uploads/{class}/{id}/{filename}', array('before' => 'auth', function()
{
return "route works";
}));
the code above works for link uploads/Deviation/1/Laravel%20Cheatsheet, but if the link is to an actual file uploads/Deviation/1/Laravel%20Cheatsheet.pdf, it seems like laravel is bypassing router. I get why does it do it, but is there a way to bend the rules for uploads folder?
By default characters like slashes and dots are not allowed in parameter values. In order to override that, you'll need to define the route as follows:
Route::get('uploads/{class}/{id}/{filename}', array('before' => 'auth', function()
{
return "route works";
}))->where('filename', '[a-zA-Z0-9\.]+');
Just make sure that you don't store the files in publicly accessible location - I suggest to store it somewhere in storage/.
The recommended Laravel Apache configuration is:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
The recommended nginx configuration is:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Both of these prioritize any files with that exact filename first, falling back to Laravel's index.php only if a file is not found. This is fairly important - you don't want the largeish PHP framework involved in serving static files like CSS/JS/images, it'd be a heavy load on the server.
If you want to sit Laravel in front of your uploads, just use a different URL to reference them, and have Laravel serve the file after you've done whatever it is you need to do.
Route::get('not-the-real-uploads/{class}/{id}/{filename}', array('before' => 'auth', function()
{
// something like this
return Response::download('uploads/...', ...);
}));

Custom routing and controller function

I have my routes.php as
$route['home'] = 'pages/home';
$route['login'] = 'pages/login';
$route['default_controller'] = 'pages/home';
and the controller pages.php as
class Pages extends CI_Controller {
public function home() {
$this->load->view('templates/header');
$this->load->view('pages/home');
$this->load->view('templates/one');
$this->load->view('templates/two');
$this->load->view('templates/footer');
}
public function login() {
//if ( ! file_exists('application/views/templates/'.$page.'.php')) {
// echo "no file";
// }
// $data['title'] = ucfirst($page);
$this->load->view('templates/header');
$this->load->view('templates/login');
$this->load->view('templates/footer');
}
}
Pre: I have just started with CodeIgniter and what I got from basic tutorial and after reading many stackoverflow answers is that a call for domain/login will be routed to function login in Pages class(controler) as per the the routing rule $route['login'] = 'pages/login';
The Problem: This simple code is showing 404 error. I am not getting it why it is so, as all the files are too present in templates folder. Also the normal call to domain works fine but if I call domain/home, again I get 404 error. Kindly help me what I am doing wrong.
So I am a bit new to CodeIgniter as well so I apologize at being so slow on this. The problem you are facing is that you haven't put in index.php. Your URL has to be domain/index.php/login. If you don't want to add index.php to every call then you must do the following:
add a .htaccess file in your application folder and have it look something like this:
<IfModule mod_rewrite.c>
# activate URL rewriting
RewriteEngine on
# the folders mentioned here will be accessible and not rewritten
RewriteCond $1 !^(resources|system|application|ext)
# do not rewrite for php files in the document root, robots.txt or the maintenance page
RewriteCond $1 !^([^\..]+\.php|robots\.txt)
# but rewrite everything else
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
ErrorDocument 404 index.php
</IfModule>
Turn on mode_rewrite (How to enable mod_rewrite for Apache 2.2 or https://askubuntu.com/questions/48362/how-to-enable-mod-rewrite-in-apache)
Restart your server
This will forward all domain/login requests to your front controller (index.php). The line RewriteCond $1 !^(resources|system|application|ext) will allow you to make certain folders NOT get rewritten. So if you have a folder under application named "resources" instead of it getting forwarded to domain/index.php/resources it will simply go to domain/resources.
In actuality without an .htaccess file the process is like this:
Check for domain/front_controller/route pattern in the URI and see if route exists and forward appropriately
By doing domain/login you were not following the pattern and so a 404 was delivered. Adding the front_controller (index.php) to the URI makes it follow the route pattern and gets forwarded to your route config.
Some people think the front controller in their URI is "ugly" so they add in a mod_rewrite which basically adds in the front_controller to the URI every time that directory is accessed. This way they can stick to domain/controller/action. This is also considered more secure as the only directories that can be directly accessed are the ones that are specifically stated in the rewrite.
Got it now !
Actually defining the
base_url = 'mysite.com'
in config.php just works for calling the default_controller in routing rule, and so your while mysite.com call will work normal and show you the home page, *interpreting default_controller* routing rule, but any calls for mysite.com/xyz will fail, even you have a function xyz in the main controller with routing rule as $route['xyz'] = 'pages/home',
as rest all URL calls have to be made as
domain/index.php/controller/function/arg,
and as suggested by #Bill Garrison, and also from the developer user guide of codeigniter, one should write rules in the .htaccess to remove index.php from domain name, and the url to router will then work as normal !!
For people reading out, one big advice well read the documentation thoroughly before firing the doubts. :)

how to make codeigniter style URI segments

I was wondering how one could make codeigniter style url segments on a project.
Aside from an htaccess rule to capture the segments, how can this be done in PHP?
After snooping around the codeigniter source code, i could not find any reference to an htaccess file that captures the usage.
Any idea on how this can be done?
Assuming you are passing ALL requests to index.php via Apache mod_rewrite or Nginx:
// Get the current URL path (only) and convert encoded characters back to unicode
$path = rawurldecode(trim(parse_url(getenv('REQUEST_URI'), PHP_URL_PATH), '/')));
// array merge with defaults
$segments = explode('/', $path) + array('home', 'index');
//First two segments are controller/method
$controller = array_shift($segments);
$method = array_shift($segments);
// #todo serious security checking here!
// Finally, load and call
$controller = new $controller;
$controller->$method($segments);
Your controller would look like this
class Home
{
public function index($params)
{
print_r($params);
}
}
What you do is set up one single url param in htaccess, and then use a string splitting method to retrieve a model, controller, and view from that string which will then call a model class, a controller class, and then render the data into a view. the transformation would be something like the following:
mysite.com/index.php?url=/tasks/all => mysite.com/tasks/all
which calls the task model, which then calls the function called "all()" inside of the tasks controller.
As soon as this site goes back online, do look at the htaccess portion of the tutorial -- he did a good job of showing how its done http://www.henriquebarroso.com/how-to-create-a-simple-mvc-framework-in-php/
You still need something to "forward" all virtual requests to a physical file.
The idea is that any URI that doesn't match a physical file or folder on disk is rewritten (usually through mod_rewrite) to your index.php file (it's usually your index file so a direct call to the index works too), and it appends the URI to the path or as a query string parameter:
RewriteCond %{REQUEST_FILENAME} !-f # Not a real file
RewriteCond %{REQUEST_FILENAME} !-d # Not a real folder
RewriteRule ^(.*)$ index.php/$1 [L] # Rewrite to index.php, with a leading slash, followed by the URI
Alternatively, you can use a standard error document handler (still in .htaccess or apache config, but no need for mod_rewrite!):
<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</IfModule>
Now that control is passed to uniformly to an index.php file, you need a router mechanism to match the route to the correct controller. Ideally, you'd have a list of static and dynamic routes. Static routes are direct matches to the URI, and dynamic would be regular expression matches. Check your static routes first, as it's as simple as a single hash lookup, while you'll have to loop through all the dynamic routes.
For performance, it's nice to put your more common dynamic routes at the beginning of the list, and the obscure ones at the end.
Using the .htaccess file to employ mod_rewrite to rewrite the base of the url is essential to this. Otherwise, the browser will treat each segment as a supposed folder or file (depending on whether or not you have a trailing /)
once you have that, however, you can simply use the method described in this post:
how do i parse url php

Categories