I'm writing a PHP library based on the zend framework. My library is used by several of my web projects. Im not sure where I should put my library. It seems to make sense to have it outside of the document root of the individual projects, so I don't have to maintain the library in every individual project. My current setup looks like this:
/var/www/vhosts/project1/
/var/www/vhosts/project2/
/var/www/vhosts/libraries/zend-framework/zend-framework-1.11.0/...
/var/www/vhosts/libraries/my-lib/my-lib-1.0.0/...
Like this, specific versions of both the zend-framework and my-lib can be used in my projects.
An alternative setup would look like this:
/var/www/vhosts/project1/
/var/www/vhosts/project1/libraries/zend-framework/zend-framework-1.11.0/...
/var/www/vhosts/project1/libraries/my-lib/my-lib-1.0.0/...
/var/www/vhosts/project2/
/var/www/vhosts/project2/libraries/zend-framework/zend-framework-1.11.0/...
/var/www/vhosts/project2/libraries/my-lib/my-lib-1.0.0/...
The first version makes more sense to me, but I'm not sure if I run into some security problems if my projects depend on files outside of their document root folders. Furthermore, I experience problems when I try to include javascript files from my-lib in my projects if my-lib is outside of the projects document root.
What's best practice here, where should I put my library and the zend framework?
If /var/www/vhosts/libraries is accessible from outside, I'd recommend you put your library one level lower (/var/www/libraries) so:
you can share the same lib with all your PHP apps
PHP can access it without tweaking the rights
it's not directly accessible from the front sites
Related
Essentially, I'm looking to have a PHP development workflow that needs to be modular, but using a Single Page Application technology.
I understand it is recommended to separate the back-end from the front-end. Develop them separately. But is there a way to group all related code into one module (or folder), meaning all backend code with its own views presentation inside the same folder?
It's like MVC, but the "V" contains fragments of vuejs (or angular) files, which extends from a master file somewhere in your project.
For example
Assume we are building a modular CMS, where you can upload "plugins" (really, PHP modules), extending the CMS' functionality:
-project[root-folder]
----core[folder] # contains all infrastracture code, api routes, master view file, magic, etc.
----modules[folder] # uploadable modules goes here
--------User[folder] # sample module; follows the MVC pattern
------------Controllers[folder] # contains files, e.g. UserController.php
------------Models[folder] # contains User.php
------------views[folder] # where vue components is housed
----------------users/index.php # contains vue code
----------------users/create.php # etc...
----------------users/js/user.js
----------------users/css/user.css
--------Blog[folder] # another module
----index.php # the master view or just the bootstrap file
----gulpfile.js
Then inside the core/ folder, there is a master layout that binds all views together.
Will a folder structure like this be viable?
Obvious problem there is you can't use .vue files (as that would mean, every time you upload a new module, you need to run gulp or re-compile).
Hoping for your feedback. Thanks.
This question will strike a lot of folk as bizarre and twisted. That's the reaction I got when I asked it in the context of .net mvc. I'm with you 100%.
I'm too new to js frontend development (and too ignorant of PHP) to have much advice. It's going to be tricky. Ajax calls to PHP code will need to go to paths below the src directory. But then you want to stop your frontend resources being served from these same paths. Both PHP and gulp will want to use file paths for urls, but at least for Gulp this can be controlled.
I'll follow this with interest. My ambition is to keep in the same folder things you're likely to want to delete together, and for those things to be able to call each other with short, relative paths. The ideal would be to be able to specify the module route independently of the path on disk, and to have this route work for both frontend bundled resources and services. Good luck !
I came across this question whilst searching for an approach for exactly the same problem. I'm building a "platform" rather than an application with a plugin system along the lines of Wordpress. I have the additional issue of the platform itself being a 'multitenancy' environment, too - so any plugins cannot interfere with the core "Dashboard" that holds these things together.
So; posting for a few reasons, two years on...
Did you get anywhere and would you care to share any thoughts?
I came across a quite extensive article for PHP Phalcon that has certainly given me a few ideas. Sharing incase it helps you/others:
https://blog.antsand.com/singlepost/index/5619/How-to-integrate-php-(Phalcon)-and-Vue.js-components
There's a line buried in the series that says "As a rule of thumb. Structure your code, based on the application and NOT on the programming language and frameworks." I'm not sure how wise or not this is, but it certainly gave me something to crack on with.
So right now, I have a module folder a bit like:
/mymodule
/Controller
/Model/
/Template
thing.vue
/Assets
/js
/css
MyModule.php
Assets are handled via a framework route (i.e, /assets/{path:.*} )
Templates are handled via the (PHP) module install script to make sure webpack knows where they live.
Still at proof-of-concept stage but rightly or wrongly, it seems to work well enough!
I have been looking into incorporating an asset management/pipelining tool (probably Assetic) into my PHP project.
Since assets can be grouped into collections or wildcard-based paths using such tools, if I wanted to set up a watch process that re-compiled/minified only those source files that had changed, how would I do that given that assets have to be looked up by name (see example below)?
(I noticed that for Symfony there's a watch task for Assetic but I'm not sure that it re-compiles only the changed file(s) and also I would have to make it work outside of Symfony since my app uses the CodeIgniter framework.)
In Assetic, you can create a wildcard-based asset, e.g.:
new GlobAsset('/path/to/compass-sources/*')
You can tell it to send the assets through a filter (Compass in this example) and then output the result (CSS) to a folder like public/css.
Let's say I set up the watch process using node.js's fs.watch so that I can theoretically tell Assetic to re-compile a particular asset whenever one of its source files changes.
Since my node.js script would only know the name of the actual file that changed (e.g. compass-sources/layout.scss), how could I look up which AssetCollection or GlobAsset that particular file belonged to (say an asset called global-styles) in order to recompile it?
I'm open to alternatives here. I looked at grunt and may very well use grunt-contrib-watch to handle the file watching, but I like the idea of using Assetic because the project is in PHP and I think that will be easier on future PHP developers working on the system who may not be familiar with node.js. It seems grunt take a different approach where assets don't necessarily go in named bundles. Mostly I want to understand the conceptual approach of named asset bundles (like in Assetic) as it relates to my goal of recompiling assets whenever the source files change.
We develop in PHP and HTML/Javascript.
Over time we developed a very big source code library, that contains a couple of hundred PHP and Javascript libraries, that we use for every project. The framework resides its own svn-repository, that we include with an external svn link in each project.
The problem is, that the entire framework itself is about 800MB now.
With only a few projects that we worked on, this wasn't really a problem, but now we have about 30 projects, that all contain a FULL copy of the framework, which takes up a lot of space, and requires constant updating of each copy.
Somehow I would like to have the framework outside the project folders. I've read about referencing other projects in Eclipse, but couldn't really get it to work.
How do you setup the include paths so that each projet 'thinks' that the framework is normally inside the project folder? And can you make a virtual link in an Eclipse project to edit files in the framework just as you would normally do, and get code assist for the libraries too?
One of the main problems is that all our code (and some libraries in the framework itself too) relies on the fact that the framework is in a folder 'framework' inside each project. I'd rather not change all those references to a different path, so maybe I need some .htaccess trick to make this work...
Does anybody else follow the same procedure?
Any advice ?
can you use the "big" project as target platform?
why-create-a-custom-target-platform
If you define it as target platform, the sources are available in your workspace, but they are placed in 1 folder for multiple workspaces. the workspaces will link to the platform, but will not check them out.
The question is quite simple : I have a controller plugin for Zend Framework.
Should I put it in the "library/Plugin" folder, or in "application/plugins".
(btw for now it is in library/Plugin but this works on Linux and Mac Os X, but not Windows so i figured maybe that is not the right place)
Thank you
If its a controller plugin it goes in "application/plugins".
If it's a general purpose plugin (ie Utility Classes and such) it goes in /library/*, where * follows the Zend Loader rules.
I generally put everything that is specific to my application, e.g. not reusable without modification into the appropriate application folder.
For generic plugins, I create a new folder in library. This folder is modeled after the Zend library folder concerning names, e.g. My/Controller/Action/Helper or My/Controller/Plugin, etc. Putting stuff there is optional though, as you might as well put this in the appropriate application folder as well. I just like the distinction.
I never put anything into the standard Zend distribution. This would get lost when updating.
What is the best way to integrate an external script into the Zend Framework? Let me explain because I may be asking this the wrong way. I have a script that downloads and parses an XML file. This script, which runs as a daily cron job, needs to dump its data into the database.
I am using Zend Framework for the site which uses this script and it seems to me that it would be best to use my subclassed model of Zend_Db_Abstract to do the adding and updating of the database. How does one go about doing this? Does my script go in the library next to the Zend Components (i.e. library/Mine/Xmlparse.php) and thus have access to the various ZF components? Do I simply need to include the correct model files and the Zend DB component in the file itself? What is the best way to handle this sort of integration?
Yes, you should put your own classes that maybe inherit Zend Framework classes or add further classes into your own folder next to the Zend Framework folder in library.
When you have Zend_Loader s auto-loading enabled, the class names will automatically map to the class you created, e.g.:
My_Db_Abstract will map to My/Db/Abstract.php .
In your library directory you should have your own library next to the Zend library folder. Whatever you call it (Mylib, Project, ...) you should include it into the Zend Autoloader and that's done as follows:
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('Project_');
$loader->setFallbackAutoloader(true);
if ($configSection == 'development')
{
$loader->suppressNotFoundWarnings(false);
}
In order for you library to integrate nicely with ZF and the Autoloader you should stick to the ZF naming conventions. This means two things:
if you extend an existing ZF class, replicate the ZF folder structure so that your file has the same path and name except for the library name. E.g. /library/Zend/Db/Abstract.php => /library/Project/Db/Abstract.php.
if you write your own classes, still stick to the ZF naming conventions for the autoloader to find them.
I just came across something that may be germane to this question. This IBM developerWorks article.
The author recommends simply creating a scripts folder in the ZF hierarchy and the using it as one normally would within ZF (though he does set the ini path and call autoload). Is it that simple? Does simply being in the hierarchy of the framework and including the path and autoloader grant your script access to all of the goodies?
I'm not 100% sure what you're trying to ask but I will try to help. If at any point you add a reference to "/path/to/zend/framework" into your php include path then you have in essence enabled the Zend Framework. From there if you do:
require_once('Zend/Loader.php');
Zend_Loader::registerAutoload();
Then at any point in your script you can pretty much just create new Zend Framework objects and Zend_Loader will handle the rest.
One of the big things about the Zend Framework though is not forcing you to do things a certain way. That's why sometimes there are several ways to accomplish the same thing. So, if you feel you need to make your script use the Zend Framework just for the sake of doing so this is not really necessary. But if you think it may improve your script in some way then go for it.
I usually put custom stuff that I think could be used across projects in a custom folder in the library. So I have a library/Ak33m folder that has scripts that may be outside of the framework.
As a ZF noob myself, I think I understand some of what the OP is trying to figure out. So, I'll just explain a bit of what I understand in the hope that it is helpful either to the OP (or more likely, to a future reader, since the original question is so old and I imagine that OP is now a ZF guru).
I understand that ZF claims to be largely "use at will", so that you need no buy into an entire structure, like the Zend_Application, the Zend_Bootstrap class, the entire MVC approach, etc.
Further, I understand conventions for class naming and file locations that enable easy autoloading. Ex: class App_Model_User resides in a folder App/Model/User.php
I think what can be potentially confusing is that in the script context, where you have not yet
done the .htaccess magic that pushes all request to public/index.php
set your APPLICATION_PATH and include paths in public/index.php
created your Application or Bootstrap object tied to a config file
it can be a little bit unclear how best to avail yourself of most of the ZF goodness we get in that context and want in another context.
I guess my answer to the original question would be that the usual entry point sequence of
http request -> .htaccess -> index.php -> config
sets up much of our environment for us, we would need to duplicate some of that for different entry path.
So, for your script, my first instinct would be to create a common include file that mirrors much of what happens in index.php - set the include paths, the APPLICATION_PATH, instantiates and calls a bootstrap, and then does your script-specific processing.
Even better, it might be desirable to create a single entry point for all your scripts, like we do in the http/web context. Extend Zend_Application for your own script purposes so that $application->run(); no longer starts up the MVC router-controller-dispatch processing, but rather does your own stuff. In that way, this single script entry point would look almost identical to the web entry point, the only difference being which application object gets instantiated. Then pass the name of your desired Application class as a command line parameter to the script.
But here I confess to being less confident and just throwing out ideas.
Hope all this helps someone. It actually helped me to write it all down. Thanks and cheers!
Update 2009-09-29: Just ran across this article: Using Zend Framework from the Command Line
Update 2009-11-20: And another article: Cron jobs in Zend Framework | GS Design
Update 2010-02-25: Easy command line scripts with Zend Application - David Caunt