I am trying to create a dynamic sitemap for my site, which runs on Zend.
I want one of my controllers to be able to write to the /public directory, but I can't figure out how to get the file written to the right place.
My relevant directory structure is something like:
.application/
....modules/
.......my_module/
..........controllers/
.............SitemapController.php
.library/
.public/
Is this a simple way in Zend to point at the public/ directory without writing something ugly like "file://../../../public/" every time?
The Zend framework bootstrap defines a constant called APPLICATION_PATH following that guideline you can initialize another constant that points to the public path:
define('PUBLIC_PATH', APPLICATION_PATH . '/../public/');
This will then be available everywhere. Make sure that the webserver has write permissions to the folder you want to store files in.
You can use $_SERVER['DOCUMENT_ROOT'] but you shouldn't -- for security, the public dir shouldn't be writable by the process that runs the web server. There are a number of ways around this. You could write the file to some other stand-alone directory outside the document root and then symlink to it. Or maybe just create a route in your app config so that the file gets generated on the fly every time.
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 completed the quickstart tutorial, but I feel really unclear on a few things. I started the guide initially expecting everything to be on my remote server, but it actually seems to be a guide for a local setup. I have everything on my server, and I have the hosts file on my local computer routing to the server, for ex. this is the entry in my hosts file server-ip quickstart.local.
1) Currently, I have everything beneath public_html. Where should I put all the Zend files (bin, demos, incubator, etc..)? www/public_html/[zend-files],www/public_html/quickstart/
2) Where do I put the quickstart (project) folder? Am I supposed to create an index.php that routes to the public folder in the project folder? At the moment, it is at public_html/quickstart/.
I feel silly and embarrassed for asking, because I feel like this is something really obvious.
Actually, you'll need only the Zend folder, which is the library itself.
On the public_html you need to put only the files located in the public folder of your project.
Folders like application and library should stay out of public_html.
For example
/home/my_project/public_html (public folder from zend)
/home/my_project/private (the other files, like application and library)
Instead of put the Zend library inside your project library folder, you can put it on the php include_path.
The second option, maybe the best, is to configure your virtual hosts and set the public folder (application public folder) as the root folder for your domain quickstart-local
So, you will end up with /home/my_project/public as your root folder and /home/my_project/application as your private folder.
You'll need to setup your index.php and application.ini with the appropriated paths.
As soon as you work with more than one framework version at a time, using symlinks becomes a good option. It is also much better for development than using the include path because you automatically have code assist for ZF code. We organize our projects as follows:
/application
/httpdocs
/library
/Project
/Zend (->symlink to the Zend folder of the needed version)
/ZendX (->dito)
/tests
And now, if you're about to say that 'symlinks' don't work on Windows, don't say it. It's utter rubish. It works perfectly well.
On my local setup I have a load of different CakePHP websites. I'm using a Mac so the folder structure is something like ~/Users/cameron/Sites/sample-website and then within each of these websites I will have the typical Cake folder and App folder.
What I would like to do is have just a core cake folder and then have ALL the sites pull from that one cake core so I don't have the same stuff several times over. I have been reading some tutorials on the web: http://rickguyer.com/cakephp-one-core-many-apps/
So I have my cake folder here: ~/Users/cameron/Sites/cake-1.3/ and then my site here: ~/Users/cameron/Sites/sample-site/ and in this folder I have the usual app folder and htaccess to tell it where to find webroot etc.
Now I have edited the index.php file inside webroot like the tutorial BUT have only changed one line because I haven't moved my files OUTSIDE of the App folder like he does. So the only like I have changed is as follows:
if (!defined('CAKE_CORE_INCLUDE_PATH'))
{
define('CAKE_CORE_INCLUDE_PATH', '..'.DS.'..'.DS.'cake-1.3');
}
As far as I can tell that is correctly looking two directories up and finding a folder called cake-1.3 however it just gives a error 500?
Any ideas what the problem is? Thanks
EDIT:
Even doing this doesn't work???
Which If I echo: echo CAKE_CORE_INCLUDE_PATH; gives /Users/cameron/Sites/cake-1.3 and if I paste that in the address bar it loads up the cake folder so it's definitely the correct folder structure JUST it doesn't like looking at cake outside of the main url?
if (!defined('CAKE_CORE_INCLUDE_PATH'))
{
define('CAKE_CORE_INCLUDE_PATH', DS.'Users'.DS.'cameron'.DS.'Sites'.DS.'cake-1.3'); echo CAKE_CORE_INCLUDE_PATH;
}
You are right on the money with:
define('CAKE_CORE_INCLUDE_PATH', DS.'Users'.DS.'cameron'.DS.'Sites'.DS.'cake-1.3');
Just make sure that Users sits in root. In other words, when you go to terminal you can get to this directory by typing: cd /Users/cameron/Sites/cake-1.3
It looks like you may be on a MAC. If so, your linking is correct. Most of the time what I find is you have done a copy paste of the app directory and it does not get the .htaccess files. I would check those first. But here is a comprehensive list of what you should verify:
Make sure the host is pointing to
the correct directory
(/Users/cameron/Sites/sample-site/)
Verify mod_rewrite is in fact on.
Verify you have copied the .htaccess
file in both the
/Users/cameron/Sites/sample-site/
and the
/Users/cameron/Sites/sample-site/webroot
directories.
Confirm that the
/Users/cameron/Sites/cake-1.3/
directory has a directory called
cake in it that contains the core.
Once all of this is confirmed, you will be good as gold!
Happy Coding!
UPDATE:
When the index.php file looks for the cake core, it will look for a directory inside the location you are pointing to for another directory called cake. So in your case:
define('CAKE_CORE_INCLUDE_PATH', DS.'Users'.DS.'cameron'.DS.'Sites'.DS.'cake-1.3');
You must have the cake directory inside /Users/cameron/Sites/cake-1.3. Your directory structure will look like:
/Users/cameron/Sites/cake-1.3/cake
/Users/cameron/Sites/cake-1.3/cake/libs
/Users/cameron/Sites/cake-1.3/cake/config
/Users/cameron/Sites/cake-1.3/cake/console
etc.
CakePHP 3.0+
In CakePHP 3.0+ this configuration is moved out of webroot/index.php to App/Config/paths.php
If you have access to your php.ini, you can add the path to Cake core there. Doing it this way means you don't have to change webroot/index.php at all. Example in php.ini:
include_path = ".:/usr/local/lib/php:/home/something/phpinc/cakephp2/lib"
According to the CakePHP 2.x docs, this is the recommended way to share the Cake core (assuming you have access to your php.ini).
You can have only one cake core but you must have one app folder (containing MVC) by site.
Is this a misunderstanding of the folder structure of CakePHP?
From the docs (CakePHP folder structure):
The app folder will be where you work your magic: it’s where your application’s files will be placed.
The cake folder is where we’ve worked our magic. Make a personal commitment not to edit files in this folder. We can’t help you if you’ve modified the core.
So the cake folder shouldn't change between all of your uses, therefore you have 1 copy. You can always change some of the functionality of the core by making your own changes in the app folder i.e. extending.
There is no need to edit index.php.
Just put an alias (or link in UNIX) to your cake folder in each of your sites folder. Works perfectly. Same goes for plugins and vendors folder.
I'm creating a weather module for an application that uses weather.com's xml service. With the license from weather.com you get a couple folders of images to use with their xml service. Is there an easy or better way to store the images in the module itself rather than the public folder of the app?
I Personaly have created a folder modules in the public folder like this:
www/htdocs/meo/public/modules
For each module i create a folder in modules folder.
/srv/www/htdocs/meo/public/modules/RandImageFrontPage/
In that folder i create 3 folders:
css,img,js
I find this is more the MVC way
Since the public folder is (or, really should be) the document root of your web server, you need to put it there. The choices are:
put the images in your module, open up your folders to the outside, making the module folder accessible (bad idea)
put the images in your module, read them and output them upon request (weird idea)
put the images in the public folder
If you put the images in something like /public/images/weater_com/* I think you still got a pretty portable/namespaced location of your images.
In a Zend Framework 1.10 application, I have a controller UsersController in a module api and in the index view of that controller I would like to reference a static asset (like a javascript file). How can I do that without putting the file in the main public?
so, we have a directory setup like this:
zfproj/
../application/modules/api/controllers/UserController.php
../application/modules/api/views/scripts/users/index.phtml
../application/modules/api/public/javascript/apimodule.js
../application/controllers/
../application/views/
../public/
I want to be able to include the apimodule.js in a view (in this case the users/index view). Ideally, this would able to be done without adding anything into zfproj/public
The intention behind this is to create a module that can be deployed into a ZF 1.10 application that is completely self-contained and does not require adding assets (like Javascript files) into the applications existing public/javascript files.
Typically all your publicly accessible assets go in public. It's meant to be the web root of your application and typically you set the DOCUMENT_ROOT of your apache virtual host to this folder. I'm not sure why you'd want to store client files (javascript, css, etc) outside the webroot. Can you elaborate more on your directory/application structure (maybe hinting at the location of the file you want to include)?
Edit
What you're asking should be possible. To make a standalone module, I think you'd just move "api" inside the primary public folder and the module would have its own bootstrap or you'd have to do something in your primary bootstrap based on the module name ("api" in this case). You'd have to modify your include paths accordingly. You'd need to add an .htaccess file to protect your code directories in this case.
../application/controllers
../public/api/controllers
../public/api/javascript/apimodule.js
../public/api/index.php
You might also create a symlink in your public folder that points to the public folder of api. So,
../public/api > ../application/modules/api/public
This would allow access to public but protect your code files. One thing I often do is check out subversion external into the public folder that just points to the public folder of the module. My CMS looks like this:
application/modules/cms
application/modules/cms/ui (public facing cms UI)
public/ui (svn:external pointing to application/modules/cms/ui)
HTH give you some ideas.