问题
I have a problem that I've seen talked about a lot on this site, but I haven't seen it talked about for applications running the php72 or php73 runtime (and if it has, I haven't seen it resolved).
I'm trying to get the basic functionality of most straightforward, php web servers, that when you navigate to a directory, it can serve the index.php that lives at that directory.
Obviously out of the box, Google App Engine doesn't do that, but I have to believe that there is a way to get that functionality.
I looked at this question, which looked like it had what I needed:
Google app engine redirect everything to index.php
The problem is, that doesn't work if you're in the php72 or php73 runtime, which I need to be. The only acceptable value for the script
name in the app.yaml file is auto
. Most all other questions have the same type of answer (in that they tell you to redefine the script value, but in my runtime that just doesn't work).
Here is my current code...I'm serving all of my images, js, and css correctly:
runtime: php73
handlers:
- url: /assets
static_dir: assets
# Serve static files as static resources.
- url: /(.+\.(gif|png|jpg|svg|webp|jpeg|js))$
static_files: \1
upload: .+\.(gif|png|jpg|svg|webp|jpeg|js)$
- url: /style
static_dir: style
- url: /js
static_dir: js
- url: /.*
script: auto
Here is my directory structure:
The index.php at the root is serving everything perfectly, it's when I try and navigate to the /forgot/
or /setup-account/
directories is when it doesn't work. And when I say doesn't work, I mean that the same content that the root index.php serves is what is shown at the /forgot/
or /setup-account/
directories.
How do I serve the index.php files from the /forgot/
and /setup-account/
directories?
回答1:
So I'm going to try and make this answer as in-depth as I can, because this was what I was searching for that I didn't really find anywhere else.
FIRST - This is using either the php72 or php73 runtime, anything before that runtime there are other answers on SO and other sites, and anything after these two runtimes, I'm just not sure.
Also, let's define my problem:
My problem was that when I would navigate to subfolders in my PHP web app (where my index.php files were that contained my controller code), the only thing that would pop up would be the content that was at my application's root (heretofore known as "/"). So, everything was being rendered and displayed correctly when I would navigate to "/", but anytime I navigated away from there, it would just keep showing the same content.
I had (and still have) no interest in a framework like Laravel, Slim, or Symfony, so I had to figure out how to do this without a framework, which proved challenging, because it looked like all of the tutorials online only dealt with frameworks. So, below is my vanilla PHP, less than 20 lines of code answer to how to do this.
1. In your app.yaml, add an entrypoint path to the script that will be your "router". Mine looks like this (look in the comments for a brief explanation):
runtime: php73
# I'm choosing to serve my router from the root of my application, and call it router.php.
# You can serve it from wherever, and call it whatever.
# So, for instance, you this line could read: serve /model/folder/path/whatever.php
entrypoint: serve /router.php
handlers:
# my handlers for css, js, and images
2. Now, in my router.php
this is the code that makes the magic happen:
<?php
require_once get_required_php_file(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
function get_required_php_file(string $path): string {
// just require the index file
if ($path === '/') {
return 'index.php';
}
// getting the last character to strip it off if it's a "/"
$last_char = \substr($path, -1);
$pathname = ($last_char === '/' ? rtrim($path, '/') : $path);
// stripping the leading "/" to get the true path
$pathname = ltrim($pathname, '/');
// setting the full require path
$full_php_path = $pathname.'/index.php';
// returning the path as long as it exists, if it doesn't, return 404.php
return (\file_exists($full_php_path) ? $full_php_path : '404.php');
}
Please see the comments for an explanation on what's happening here...although it should be pretty self explanatory. I'm taking the request_uri from the user and just appending index.php onto the pathname and requiring it.
So, that's that. A cheap, vanilla router in 12 lines of code (if you eliminate the whitespace and comments).
GOTCHAS
1. If, like me, you have view files that include headers and/or footers like this:
// view.php
<?php
declare(strict_types=1);
include_once '../view/header.php';
include_once '../view/footer.php';
You need to go through and change your include paths to include from where your router file is. For my example, it's easy, because I put my router at the root. So if I wanted to update the above incorrect view example to correctly include the files, that above code would now look like this:
// view.php
<?php
declare(strict_types=1);
include_once 'view/header.php';
include_once 'view/footer.php';
回答2:
This is great! Thankyou.
I needed one small tweak to make it work for me.
I served pages with the name of each php file exposed.
Like this:
myurl.com\formfrontend.php or myurl.com\mygmailservice.php
So I needed to change the line:
$full_php_path = \ltrim(\rtrim($path, '/'), '/').'/index.php';
to this:
$full_php_path = \ltrim(\rtrim($path, '/'), '/');
来源:https://stackoverflow.com/questions/57206392/default-routing-to-route-to-directory-index-php-google-app-engine