I have a strange problem. I want to turn off the auto generating of my proxies in Doctrine 2. I found this line of code that should do (and does) the trick:
$config->setProxyDir(APPPATHSYSTEM."/proxies");
$config->setProxyNamespace('Proxies');
// Auto generate proxies for development
$config->setAutoGenerateProxyClasses(DEVELOPMENT);
On my test environment the proxies are located at application/proxies. i.e.:
application/proxies/BaseUserProxy.php
When I'm on the live environment my code suddenly searches for the proxies at application/proxies/Proxies which is not the actual location.
I do understand it has something to do with the namespace, but I don't understand why it behaves differently when using the setAutoGenerateProxy method.
Any ideas?
edit
I did generate the new proxies using the:
orm:generate-proxies
option.
Which gave me this output:
php doctrine.php orm:generate-proxies
Processing entity "Base\Element"
Processing entity "Base\Page"
...
Processing entity "Base\Site"
Proxy classes generated to "/var/www/application/proxies"
Looking at the last line, the proxies are generated in /var/www/application/proxies. The directory listing looks like this:
BaseElementProxy.php
BasePageProxy.php
...
BaseSiteProxy.php
So there is no extra Proxies directory. But when I refresh my webpage it thinks there is, it gives me the following error:
Warning: require(/var/www/application//proxies/Proxies/BaseUserProxy.php)
[function.require]: failed to open stream:
No such file or directory in /var/www/library/Doctrine/Common/ClassLoader.php on line 148
Why is the extra Proxies directory added? If I do generate the proxies on each request it does not look in the extra Proxies directory. Anybody?
#Bryan M.: That is not a solution, but a workaround. Besides, it does not work. When generating the proxies they will, if applying your suggestion, be generated in APPPATHSYSTEM and my webapp will try to load them from APPPATHSYSTEM."Proxies". The problem is that the system looks for the proxies on different locations if I use:
$config->setAutoGenerateProxyClasses(DEVELOPMENT);
If DEVELOPMENT is true, it will look at APPPATHSYSTEM. If DEVELOPMENT set to false, it will look at APPPATHSYSTEM."Proxies". Just switching the DEVELOPMENT constance breaks my application, what theoretically should not be possible.
I don't think AutoGenerated proxies care.
Instead of pushing autogenerated proxies to production, you should probably doctrine orm:generate-proxies, which I suspect will put them in the place your production code is configured to look for them.
Are you developing on OS X and deploying to Linux? OS X's filesystem is case insensitive. So I'll often run into a problem where I mistype the case of a class, and it runs and passes just fine in the local environment, but chokes on our server.
So in this case, in OS X, the namespace "Proxies" is able to resolve to "/proxies", but in production, it can't find the class folder, and creates it under "/proxies/Proxies".
If you rename the folder to something called "/temp" you will realize the difference between path and namespace.
The path is the absolute path to the directory the proxies are getting generated into. The namespace is necessary to allow you to configure how an autoloader picks up these entities.
The path in your case has to be something like "proxies/Proxies" and the namespace is then "Proxies". Your autoloader has to be configured to listen to namespace prefix "Proxies" at directory "proxies/".
This is all mood with Doctrine 2 RC1 though, we found a way to explicitly load a proxy path without help of an autoloader at no additional cost. The Proxy Namespace configuratino is therefore only necessary to make sure no other classes are in the same namespace as the proxies.
Related
I'm trying to use the Composer autoloader located at vendor/autoload.php. However, I can't seem to figure out how to get to the root of the project, from which I could then navigate to vendor/autoload.php. I'm having to specify the relative path in each file (i.e. ../../../vendor/autoload.php). This seems like a very nasty way to get to the autoloader, since this path will be different depending on how deep the file is.
Is there a way to get to the root directory without specifying a relative path, or do I need to go up x parent directories in every file?
PHP has no way of knowing what the "root of the project" is. You could have any number of directories on your disk, with files called vendor/autoload.php in several of them, and only you know what's special about the "project root". So ultimately, the answer is no, there is no way.
However, note that you only need to include the autoloader in files which aren't themselves included or autoloaded. The autoloader is something you load once, as part of the configuration / bootstrapping of your code, and it then loads whatever classes it needs wherever they're referenced.
So the way to limit the mess of different levels is to structure your project carefully. For instance:
Route all requests via one or two "routers", such as a single "index.php" file. Use Apache mod_rewrite or the equivalent in Nginx etc to make all URLs actually load this script, and then in the script work out what code to run based on the URL. You can use libraries such as nikic/FastRoute to translate the URLs into functions to call, which will then be autoloaded.
Use different PHP files, but all in a reasonably flat directory structure, so that they all have to "climb" the same number of levels to reach the project root.
The same principle applies to use in command-line scripts or any other kind of application: limit or structure the "entry points", because only those need to know where to load the autoloader.
If you already have some kind of config file loaded on every request / script run / unit test / etc, it might be sensible to put the require_once 'vendor/autoload.php'; line in there. Like the configuration, the autoloader is "global state" that you want to just set up once and then forget about.
I have a php application that relies on several classes to function properly. If I take one of the application's class files
/my/folder/class.php
then move it somewhere else
mv /my/folder/class.php /my/other/folder/class.php
then in its place inside of
/my/folder/
I create a symlink to it called class.php via
ln -s /my/other/folder/class.php /my/folder/class.php
I would expect my application to be unaffected, but instead this is breaking it. I know the symlink is valid since at the command line I can do
nano /my/folder/class.php
and everything looks as I would expect it to. Am I missing something fundamental about the behavior of symlinks, and/or how apache or php processes them? Is it changing the working directory or $_SERVER['DOCUMENT_ROOT']? I can not figure out why this would have any affect on my application.
I am using Apache server in CentOs.
Thanks!
The only difference would be if you are using require_once or include_once and you are mixing the symlink path with the real file path. In this instance, the X_once is going to think those files are different and load it twice (which will of course cause problems if you define any classes or functions).
Would probably need an actual error message to guess any further.
I have the Laravel Administrator Plugin and I set up a setting administrator page that is located in:
app/config/administrator/settings/site.php
The application can store the data, but when i try to get some data in one of my controllers like this:
Config::get('administrator.settings.site')
I can get a returned value... Always null or array 0.
How I can get those configuration values?
Solution:
You can use a file path rather than dot notation for file paths:
Config::get('administrator/settings/site.variable_name');
Some Explanation
Dot notation is used to get variables inside the config array within a file, rather than to denote file paths.
Therefore you can use Config::get('administrator/settings/site.variable_name'); to get $variable_name from administrator/settings/site.php, or ENV_DIR_NAME/administrator/settings/site.php depending on your environment.
Directories within in app/config are read as environments. For example app/development/database.php will work with Config::get('database.whatever') when you're in your "development" environment while app/production/database.php will be read with Config::get('database.whatever') when you're in the "production" environment.
Laravel falls back to the config/config/*.php file when no environment-specific file is present.
Note
I believe that admin package has a config file in app/config/packages/frozennode/administrator/administrator.php which the package would like you to use for it's settings. That should be available using this convention: Config::get('package::file.option');
I ran into a very similar problem when using this Laravel-Excel package.
The solution I needed was slightly different to the solution above. I needed to take advantage of Laravel's config overriding feature to have one config setting for normal execution and a different one for testing. Specifically, I normally wanted Excel files to be stored in storage/excel and I wanted them to be put in storage/testing/excel under testing.
The technique of using a slashed path didn't work because it points to a specific file so didn't respect the different environments:
$directory = Config::get('packages/maatwebsite/excel/export.store.path');
The solution was to use a package prefix so that the config loader would respect the environment:
$directory = Config::get('excel::export.store.path');
I'm not exactly sure where the excel shorthand name comes from but I suspect it's something to do with the Excel facade in the package exposing itself as 'excel'.
How do I have Symfony 2 ignore hidden files? If I edit my source tree, my Mac puts all kinds of .AppleDouble directories everywhere and I get errors like this (when running a command via CLI):
The autoloader expected class
"Thing\CoreBundle\Command.AppleDouble\EnsureIndexesCommand" to
be defined in file
"/var/www/mysite.com/Symfony/app/../src/Thing/CoreBundle/Command/.AppleDouble/EnsureIndexesCommand.php".
The file was found but the class was not in it, the class name or
namespace probably has a typo.
The .AppleDouble directory contains a file that ends in "Command.php" which is picked up by Symfony which thinks it's a valid command file when it's just serving some OSX purpose.
I see that there's an ignoreDotFiles option that is set on by default in the Finder.php constructor, but it apparently has no effect:
https://github.com/symfony/symfony/commit/7ab3fdeb8325d5a72c44dc73214c97f366a11c4c
I have to clean the source tree before I run every command which gets old and makes the Mac filesystem & Eclipse unstable since those hidden files are there for a reason.
I use CloudControl for hosting and I would like to set up a server (possibly with load balancing support) to host piwik for all of my websites. The only problem is that the only writable directory CloudControlled allows you to access is defined by $_SERVER['TMPDIR'].
Is it possible to modify piwik to use this directory for all of its file-writing needs?
And also will I run into any issues with using load balancing? Something like automatically generated reports being generated by each node behind my load balancer since they're not aware of each other?
The idea is to keep this change for your system even when you update.
This is easy to do: create a bootstrap.php inside the piwik main folder.
This is the content of said file:
<?php
define('PIWIK_USER_PATH', $_SERVER['TMPDIR']);
You can double-check this: in index.php, you should see that it checks for a bootstrap.php file in the same folder. It's included when available, and this allows you to do little customizations and keep them even when you update. E.g. I've run piwik from svn for the past three years or so and have some custom changes in there.
There's far too much code for me to be able to confirm this works, but the constant PIWIK_USER_PATH seems to be used as the base root for file io. With that in mind, editing index.php, around line 23, which is originally:
if(!defined('PIWIK_USER_PATH'))
{
define('PIWIK_USER_PATH', PIWIK_DOCUMENT_ROOT);
}
To something like:
if(!defined('PIWIK_USER_PATH'))
{
define('PIWIK_USER_PATH', $_SERVER['TMPDIR']);
}
Might work - but then what happens when it's trying to read a file in its original location? Since this is a temporary directory, however, it may not be viable, in which case an approach using override_function or a similar method, paired with a persistent storage (your database), might also work - by overriding file functions with a database load/save routine; obviously this opens up another can of worms of biblical proportions, thus, my final recommendation is for you to get another less restrictive host.