Default routing to route to /directory/index.php Google App Engine

|▌冷眼眸甩不掉的悲伤 提交于 2020-04-30 08:27:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!