PHP Built-in Webserver and Relative Paths - webserver

TL;DR
Does PHP 5.4 built-in webserver have any bug or restriction about relative paths? Or does it need to be properly (and additionally) configured?
When I used to programming actively I had a system working under URI routing using these lines in a .htaccess file:
RewriteEngine On
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php [L]
The FrontController received the Request, find the proper route from given URI in a SQLITE database and the Dispatcher call the the Action Controller.
It worked very nicely with Apache. Today, several months later I decided to run my Test Application with PHP 5.4 built-in webserver.
First thing I noticed, obviously, .htaccess don't work so I used code file instead:
<?php
if( preg_match( '/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"] ) ) {
return false;
}
include __DIR__ . '/index.php';
And started the webserver like this:
php.exe -c "php.ini" -S "localhost:8080" "path\to\testfolder\routing.php"
So far, so good. Everything my application need to bootstrap could be accomplished by modifying the include_path like this:
set_include_path(
'.' . PATH_SEPARATOR . realpath( '../common/next' )
);
Being next the core folder of all modules inside a folder for with everything common to all applications I have. And it doesn't need any further explanation for this purpose.
None of the AutoLoader techniques I've ever saw was able to autoload themselves, so the only class manually required is my Autoloader. But after running the Test Application I received an error because my AutoLoader could not be found. o.O
I always was very suspicious about realpath() so I decided to change it with the full and absolute path of this next directory and it worked. It shouldn't be needed to do as I did, but it worked.
My autoloader was loaded and successfully registered by spl_autoload_register(). For the reference, this is the autoloading function (only the Closure, of course):
function( $classname ) {
$classname = stream_resolve_include_path(
str_replace( '\\', DIRECTORY_SEPARATOR, $classname ) . '.php'
);
if( $classname !== FALSE ) {
include $classname;
}
};
However, resources located whithin index.php path, like the MVC classes, could not be found. So I did something else I also should not be doing and added the working directory to the include_path. And again, manually, without rely on realpath():
set_include_path(
'.' . PATH_SEPARATOR . 'path/to/common/next'
. PATH_SEPARATOR . 'path/to/htdocs/testfolder/'
);
And it worked again... Almost! >.<
The most of Applications I can create with this system works quite well with my Standard Router, based on SQLITE databases. And to make things even easier this Router looks for a predefined SQLITE file within the working directory.
Of course, I also provide a way to change this default entry just in case and because of this I check if this file exist and trigger an error if it doesn't.
And this is the specific error I'm seeing. The checking routine is like this:
if( ! file_exists( $this -> options -> dbPath ) ) {
throw RouterException::connectionFailure(
'Routes Database File %s doesn\'t exist in Data Directory',
array( $this -> options -> dbPath )
);
}
The dbPath entry, if not changed, uses a constant value Data/Routes.sqlite, relatively to working directory.
If, again, again, I set the absolute path manually, everything (really) works, the the Request flow reached the Action Controllers successfully.
What's going on?

This a bug in PHP's built-in web server that is still not fixed, as of PHP version 5.6.30.
In short, the web server does not redirect to www.foo.com/bar/ if www.foo./bar was requested and happens to be a directory. The client being server www.foo.com/bar, assumes it is a file (because of the missing slash at the end), so all subsequent relative links will be fetched relative to www.foo.com/instead of www.foo.com/bar/.
A bug ticket was opened back in 2013 but was mistakenly set to a status of "Not a Bug".
I'm experiencing a similar issue in 2017, so I left a comment on the bug ticket.
Edit : Just noticed that #jens-a-koch opened the ticket I linked to. I was not awar of his comment on the original question.

Related

Trying to return a static file in web.py but getting "not found" error message

I have a web.py server hosted on pythonanywhere.com doing some handy things with python.
Now I'd like to just serve a straightforward html file from the same server i.e. just return the contents of a static html file to the client
The comments/answers below state that it should be possible, out of the box, to serve static files in the static directory, located in the same directory as the main python file which contains the following :
import web
urls = (
'/', 'hello'
)
app = web.application(urls, globals())
class hello:
def GET(self):
return 'Hello, Joe'
if __name__ == "__main__":
app.run()
The server above works fine, when I go to http://myhost/ it displays "Hello , Joe".
The directory static exists and contains a file small.jpg but when I try the url http://myhost/static/small.jpg it gives me "not found"
Previous text of question up to Nov 9th 2022 is below :
original question title : Trying to return a html file in web.py but getting "No template named ....." error message
So I've looked at the web.py documentation on serving static files and templating and I think the following code should work :
import web
render = web.template.render('static/')
# have also tried render = web.template.render('/full/path/to/static/')
urls = (
'/getlatlongEIRCODE', 'getlatlongEIRCODE', #other stuff
'/getlatlongGOOGLE', 'getlatlongGOOGLE', #other stuff
'/getmonthlyPV', 'getmonthlyPV', #other stuff
'/Tomas', 'Tomas',
)
class Tomas:
def GET(self):
return render.Tomas()
I have created a folder static at the same level as my file above (which works fine for the other scripts) and i have created a file Tomas.html in the static folder containing
<h1>Help me</h1>
However I get an error message when I go to https://example.com/Tomas
<class 'AttributeError'> at /Tomas
No template named Tomas
P.S. From the static files page it seems to say I should just be able to put the Tomas.html file in a folder called "static" and then access is via https://example.com/static/Tomas.html but that is not working (it returns "not found")
You're using a relative path to your template directory without paying attention to the working directory. See https://help.pythonanywhere.com/pages/NoSuchFileOrDirectory/
You're working too hard. 'static' is built in.
As the documentation says, http://localhost/static/logo.png will return the file logo.png from the existing directory static, which is relative to your webserver root.
Do not use render() for this (not needed). Also, do not list your desired file ('/Tomas') in the urls list (not needed).
Anything under the static directory can be accessed with the url https://localhost/static/...
"static" is hardcoded in the web.py server, so you cannot (easily) change this to some other folder. The suggestion in the web.py documents is to have nginx or apache host your application and use an Alias there to go to web.py static. (I think you can also add StaticMiddleware to your web.py application, but you'd need to investigate that yourself -- look at web.application.run()
The case of the disappearing /static/ directory was related to the fact that I'm hosting on pythonanywhere.com
Even though the web.py documentation says that the /static/ folder is plugged in by default, that's not the case in pythonanywhere and you need to expressly make the link between the url http://yourhost/static/ and /path/to/static in the Web part of the dashboard.

How to run custom php script from doc root in magento2

I wanted to add custom php script to magento2 root folder and run from the browser.I tried to add it in magento2 root folder but it redirects to 404 page.
I also tried to add it in pub folder but no success.
Also cleared cache and empty generation folder.
I am using nginx server
If you are using nginx configuration that comes with magento you need to put a file inside pub folder to allow access to it from the browser as pub is the document root of the vhost. Magento root dir is one level up. Second of all default config for nginx allows only to access index.php, get.php, static.php, report.php, 404.php and 503.php files. Any other are not processed by the php. You can see this in line with location ~ (index|get|static|report|404|503)\.php$ { in nginx.conf.sample. If you are not using it check your config for similar rule. To allow another file to be accessible from browser simple add another name after 503 or change entire brackets with location ~* \.php$ {
Source: https://magento.stackexchange.com/a/97290/1883
For example you can get product name in custom script by this step
step 1: create index.php at root of magento 2
magento2/test/index.php
<?php
require __DIR__ . '../../app/bootstrap.php';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
$app = $bootstrap->createApplication('customScript');
$bootstrap->run($app);
step 2: create customScript.php
magento2/test/customScript.php
<?php
class customScript
extends \Magento\Framework\App\Http
implements \Magento\Framework\AppInterface {
public function launch()
{
$this->_state->setAreaCode('frontend'); //Set area code 'frontend' or 'adminhtml
$id = 12;
$_product = $this->_objectManager->create('\Magento\Catalog\Model\Product')->load($id);
echo $_product->getName();
return $this->_response;
}
public function catchException(\Magento\Framework\App\Bootstrap $bootstrap, \Exception $exception)
{
return false;
}
}
Now you can run this custom script by
http://10.16.16.196/magento2/test/
As stated by #Ranjit, the /pub folder must be your Magento root folder.
The correct way to run a standalone php script on Magento would be:
On nginx:
Locate location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ { and add your file there.
I.e:
location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check|myphp)\.php$ {
Then you can access yourstore.com/myphp.php.
On Apache:
Simply add the file under /pub folder. I.e.: /pub/myphp.php.
Apache rewrites rule will redirect to index.php if the file or folder doesn't exist.
In my case on Apache (cPanel) the problem was that file permissions of .php files should not be writable by group or others to be served directly, else Magento's 404 would open.
So in my case to serve file directly I had to set file permission to -rw-r--r-- (on Linux).
This is the mostly issue with servers using suPHP.
Putting this here in case someone runs into same situation...

Ocramius / Doctrine & Zend validate-schema Acess denied

I am doing the tutorial from Marco Pivetta for Ocramius and Zend, I am stuck at the step where I should validate the schema. (See here: Link to the tutorial )
So actually I am stuck at the same point like at this question, already asked on stackoverflow.
The author on this question found the solution obviously, but for me it's not working.
He writes
And, if you use gitBash don't forget if you have tested your APPLICATION_ENV variable in application.config.php like this tutorial Zf2 advances config setup do in bash_profile file.
export APPLICATION_ENV="development"
I did this in my application.config.php
$env = getenv('APP_ENV') ?: 'development';
// Use the $env value to determine which modules to load
$modules = array(
'ZendDeveloperTools',
'Application',
'DoctrineModule',
'DoctrineORMModule',
);
if ($env == 'production') {
$modules[] = 'ZendDeveloperTools';
}
return array(
'modules' => $modules,
[...]
But I still get the error
[PDOException]
SQLSTATE[HY000] [1045] Access denied for user 'username'#'localhost' (using password: YES)
I have to say though, I couldn't figure out what the author means with the
[... ] bash_profile file:
export APPLICATION_ENV="development
His sentence is written without regarding any grammatical sense.
So the problem is:
Somehow my doctrine.local.php in the autoloads is ignored, I can't figure out why.
I am using GitBash for the
./vendor/bin/doctrine-module orm:validate-schema
command.
Got it:
Make sure you are using GitBash and ZendStudio in administrator mode -.-

Opencart Fatal error: Call to a member function get() on a non-object

Trying to move from local host to new server. Fresh install worked fine, no problems. When I uploaded my files mydomain.com/admin comes up with a white screen and mydomain.com produces this error:
Fatal error: Call to a member function get() on a non-object in /home4/pawpostc/public_html/index.php on line 103.
So I took a look at index.php line 103:
if ($config->get('config_error_display')) {
echo '<b>' . $error . '</b>: ' . $errstr . ' in <b>' . $errfile . '</b> on line <b>' . $errline . '</b>';
}
Seems like there is a problem with my config files. So I went and had a look at them. I have gone over them a few times but can not find the mistake, probably missing something, so here are the config files.
config.php (in my root www. folder):
<?php
// HTTP
define('HTTP_SERVER', 'http://www.pawpost.com.au/');
define('HTTP_IMAGE', 'http://www.pawpost.com.au/image/');
define('HTTP_ADMIN', 'http://www.pawpost.com.au/admin/');
// HTTPS
define('HTTPS_SERVER', 'http://www.pawpost.com.au/');
define('HTTPS_IMAGE', 'http://www.pawpost.com.au/image/');
// DIR
define('DIR_APPLICATION', '/home4/pawpostc/public_html/catalog/');
define('DIR_SYSTEM', '/home4/pawpostc/public_html/system/');
define('DIR_DATABASE', '/home4/pawpostc/public_html/system/database/');
define('DIR_LANGUAGE', '/home4/pawpostc/public_html/catalog/language/');
define('DIR_TEMPLATE', '/home4/pawpostc/public_html/catalog/view/theme/');
define('DIR_CONFIG', '/home4/pawpostc/public_html/system/config/');
define('DIR_IMAGE', '/home4/pawpostc/public_html/image/');
define('DIR_CACHE', '/home4/pawpostc/public_html/system/cache/');
define('DIR_DOWNLOAD', '/home4/pawpostc/public_html/download/');
define('DIR_LOGS', '/home4/pawpostc/public_html/system/logs/');
// DB
define('DB_DRIVER', 'mysql');
define('DB_HOSTNAME', 'localhost');
define('DB_USERNAME', 'my user name');
define('DB_PASSWORD', 'my password');
define('DB_DATABASE', 'my database');
define('DB_PREFIX', 'oc_');
?>
admin/config.php:
<?php
// HTTP
define('HTTP_SERVER', 'http://www.pawpost.com.au/admin/');
define('HTTP_CATALOG', 'http://www.pawpost.com.au/');
define('HTTP_IMAGE', 'http://www.pawpost.com.au/image/');
// HTTPS
define('HTTPS_SERVER', 'http://www.pawpost.com.au/admin/');
define('HTTPS_CATALOG', 'http://www.pawpost.com.au/');
define('HTTPS_IMAGE', 'http://www.pawpost.com.au/image/');
// DIR
define('DIR_APPLICATION', '/home4/pawpostc/public_html/admin/');
define('DIR_SYSTEM', '/home4/pawpostc/public_html/system/');
define('DIR_DATABASE', '/home4/pawpostc/public_html/system/database/');
define('DIR_LANGUAGE', '/home4/pawpostc/public_html/admin/language/');
define('DIR_TEMPLATE', '/home4/pawpostc/public_html/admin/view/template/');
define('DIR_CONFIG', '/home4/pawpostc/public_html/system/config/');
define('DIR_IMAGE', '/home4/pawpostc/public_html/image/');
define('DIR_CACHE', '/home4/pawpostc/public_html/system/cache/');
define('DIR_DOWNLOAD', '/home4/pawpostc/public_html/download/');
define('DIR_LOGS', '/home4/pawpostc/public_html/system/logs/');
define('DIR_CATALOG', '/home4/pawpostc/public_html/catalog/');
// DB
define('DB_DRIVER', 'mysql');
define('DB_HOSTNAME', 'localhost');
define('DB_USERNAME', 'my user name');
define('DB_PASSWORD', 'my password');
define('DB_DATABASE', 'my database');
define('DB_PREFIX', 'oc_');
?>
Any help on this would be appreciated.
I was using opencart and installed vqmod.
All of a sudden I have one of the same errors.
This solved my problem:
in system/library/session.php
replace start session with:
session_save_path(realpath(dirname($_SERVER['DOCUMENT_ROOT']) . '/../tmp'));
The most likely issue is that one or more of your library files are corrupt from uploading. Re upload your system/library/ folder from your local one. Your config files seem fine and the error doesn't reference a config issue. What is line 103 in your index.php file?
please cross check you have set all permissions
i had came across this error and was solved,
that was due to a file permission problem
I was struggling with the same problem after migrating my site to a new VPS environment. I figured it HAD to be something to do with the changed document-root path or permissions of my shop and pulled out a lot of hair trying to get to the core of the problem.
I finally realised that I had incorrect permissions on my PHP session-data store! In my case, the folder at /var/lib/php/session/ was owned by apache (naturally) but I had changed apache to run as a different user so it could no longer write to the session-store.
The error messages in this case are cryptic (to say the least!) and didn't give a clue that the problem might just be lack of write permission!
Oh well, we should know by now that 90% of unix issues are down to perms!
I upload a file at my server (directory: vqmod/....php ).
Just change vqmod file permission. I set 777 and that solved it.
From the error you received, it looks like the $config variable is not getting set.
The $config variable is set on line 35 using the Config class which is located in system/library/config.php
I think if you figure out why the class isn't getting instantiated, you'll be able to fix the issue.
This could be a couple things:
The system/library/config.php file may not have been uploaded to the new server
As mentioned in previous answers, there could be a permissions issue. Check the permissions of system/library/config.php and make sure the correct user has ownership.
Or it could be a completely unrelated issue.
The error is due to permissions set on the cache folder. Setting that to 755 and the files to 555 with set you home and dry.
I had the same issue. I changed vqmod permission to 777. I am not sure this solved the problem, but I checked my website without adding www. before the domain and it worked. The warning was removed if I check http://daytodaystore.com. If I check http://www.daytodaystore.com, the warning is there.
I had this problem when i migrated my server from 2G to 4GH on Godaddy.
Came across this forum and found that the issue is with session.php
Then, i guessed 'tmp' folder was missing. So, i created one just one step above html folder. and gave it a 777 access. Problem was fixed and my website looks great after that.

How to change include directory of Zend Framework

I get the following error messages:
Warning: include_once(Zend\Db.php) [function.include-once]:
failed to open stream: No such file or directory in
C:\EasyPHP3\www\VPZ\Lib\Zend_1.7.7\Loader.php on line 83
Warning: include_once() [function.include]:
Failed opening 'Zend\Db.php' for inclusion (include_path='VPZ/') in
C:\EasyPHP3\www\VPZ\Lib\Zend_1.7.7\Loader.php on line 83
Warning: require_once(Zend/Exception.php)
[function.require-once]: failed to open stream:
No such file or directory in
C:\EasyPHP3\www\VPZ\Lib\Zend_1.7.7\Loader.php on line 87
Fatal error: require_once() [function.require]:
Failed opening required 'Zend/Exception.php' (include_path='VPZ/') in
C:\EasyPHP3\www\VPZ\Lib\Zend_1.7.7\Loader.php on line 87
i want to include ZendXXX\Db.php
how to change it
create a directory (say 'lib'), and put your Zend directory in it. so your directory structure looks like this:
- application
- lib
|- Zend
- wwwroot
|- index.php
now you should add lib to your include path. edit your index.php file:
$includePath = array();
$includePath[] = '.';
$includePath[] = './../application';
$includePath[] = './../lib';
$includePath[] = get_include_path();
$includePath = implode(PATH_SEPARATOR,$includePath);
set_include_path($includePath);
now you have your lib in your include path. you can include all Zend components like this:
include 'Zend/Loader.php';
require_once 'Zend/Db.php';
the best way is too include Zend_Loader first and then use it to load classes. do this:
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Db');
you can also register to autoload classes. just add this line to your code after all those before:
Zend_Loader::registerAutoLoad('Zend_Loader',true);
now you do not need to include files to call classes. just instanciate your classes:
$session = new Zend_Session_Namespace('user');
there is no need to include 'Zend/Session/Namespace.php'.
Use set_include_path(). See PHP.net documentation
Example:
set_include_path(get_include_path() . PATH_SEPARATOR . '/path/to/Zend');
I usually store the framework files under a "library" folder:
application
public_html
library
Zend
Common
etc....
and then in my bootstrap file, or front controller, I add that "library" folder to the include path:
set_include_path(get_include_path() . PATH_SEPARATOR . '../library');
See also:
Choosing Your Application's Directory Layout.
Create the Filesystem Layout.
The reason the other suggestions say anything about doing that, is because it's a bad move - in other words, you're doing it wrong.
You can create a subdirectory and name it Zendxxx, but then you have to add that to your include_path, and change it, whenever you put a newly named version up.
I'd hazard a guess, and say that you don't have a good way to test the website (so you want to lock it to a particular version of ZF), and further, that you aren't using revision control, so you want all the previous versions of code in the site-directory to be able to go back to, if you find a problem when you change the live-running code directly on the server.
project without library And including library from one location
project C:\xampp\htdocs\my\application
library C:\xampp\Zend\library
make changes in index.php
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR,
array(realpath(APPLICATION_PATH.'/../../../Zend/library'),get_include_path(),)));