Good morning,
I'm currently learning Zend 2 but already have experience in MVC. I installed the current zend2 skeleton application, which is reachable under http://learningzend.local/ on my local machine.
Now, I'm trying to understand Zends routing but I'cant reach /application/index/index. It returns 404.
Here is an excerpt from module.config.php. The only thing I changed was the type in the two latter routes, it was originally set to 'Literal' and 'Segment' without the path. The home route seems to work: when I change the action, the homepage disappears.
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
// The following is a route to simplify getting started creating
// new controllers and actions without needing to create a new
// module. Simply drop new controllers in, and you can access them
// using the path /application/:controller/:action
'application' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
And few lines below
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController'
),
),
The controller is completely unchanged
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController
{
public function indexAction()
{
return new ViewModel();
}
}
I tried everything. Resetted the whole skeleton app to default but it did not change anything. Hope some Zend gurus can tell me whats wrong.
For completeness my VHOST entry
<VirtualHost *>
ServerName learningzend.local
ServerAdmin webmaster#localhost
DocumentRoot /var/www/learningzend.local/public/
AccessFileName .htaccess
<Directory /var/www/learningzend.local/public/>
Options Indexes FollowSymLinks MultiViews
DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Here comes....the solution!
The Apache2 setting AllowOverride in my VHOST conf does not override the same setting in apache2.conf, even if they point to different directories. So, go to
$ sudo joe /etc/apache2/apache2.conf
Change the Setting at /var/www to
AllowOverride All
$ sudo service apache2 restart
Related
I'm just starting off with Zend Framework, and I'm not quite sure what I'm doing wrong with the URI routing.
I'm starting with an initial Zend Framework project in Zend Studio based in my htdocs folder (I'm using Zend Server as well on Windows 7). Everything up to there seems to be working fine getting the index page up (it's running out of the /public/ subdirectory).
But when I try to add a module though, in this case called Users with a controller called Index, and following the instructions in getting that configured, I'm not sure what I should be putting in the URI to get it to route to it's view. I've tried just about every configuration of URI combinations that I can think of (localhost:80/public/users, localhost:80/public/users/index, localhost:80/users, etc)
I'm not getting a routing error, but just a plain 404 page.
Do I need to set the public folder as the root? Or is there something else I need to do to get the routing to work?
~edit in response to bitWorking
It looks like it does automatically add it to the application.config.php. But here is the module.config.php of the Users module
'router' => array(
'routes' => array(
'users' => array(
'type' => 'Literal',
'options' => array(
// Change this to something specific to your module
'route' => '/index',
'defaults' => array(
// Change this value to reflect the namespace in which
// the controllers for your module are found
'__NAMESPACE__' => 'Users\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
// This route is a sane default when developing a module;
// as you solidify the routes for your module, however,
// you may want to remove it and replace it with more
// specific routes.
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
),
),
Now I do see where it's guiding you to customize the routes. I've experimented with this as well, but still am not sure what I should set them to. Much closer though.
If you want to call the Index controller in your Users module with /users you have to name the route accordingly:
...
'users' => array(
'type' => 'Literal',
'options' => array(
// Change this to something specific to your module
'route' => '/users',
---------
...
Else please control the application.config.php. It should look like:
return array(
'modules' => array(
'Application',
'Users',
),
...
So the Url's should look like:
localhost/public/users -> Users/Controller/IndexController/indexAction
localhost/public/users/foo -> Users/Controller/FooController/indexAction
localhost/public/users/foo/bar -> Users/Controller/FooController/barAction
I am newbie to zend framework and i am trying to configure the zend. I was sucessfully installed zendskeleton applicaion on window 7 and XAMPP
After installation I am creating new module Album as per define in user guide. I was make all code and pages according to guide, but after that i was enable to open Album module. i got error 404 not found.
here code
application.config
return array(
'modules' => array(
'Application','Album',
),
'module_paths' => array(
'./module',
'./vendor',
),
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
),
);
module.config
return array(
'controllers' => array(
'invokables' => array(
'Album\Controller\Album' => 'Album\Controller\AlbumController',
),
),
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'album' => __DIR__ . '/../view',
),
),
);
Module.php
namespace Album;
// Add these import statements:
use Album\Model\Album;
use Album\Model\AlbumTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
class Module
{
// getAutoloaderConfig() and getConfig() methods here
// Add this method:
public function getServiceConfig()
{
return array(
'factories' => array(
'Album\Model\AlbumTable' => function($sm) {
$tableGateway = $sm->get('AlbumTableGateway');
$table = new AlbumTable($tableGateway);
return $table;
},
'AlbumTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Album());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
}
httpd-vhosts.conf
<VirtualHost *:81>
ServerName zf2-tutorial.localhost
DocumentRoot "C:/xampp\htdocs/ZendSkeletonApplication/ZendSkeletonApplication-master/public"
SetEnv APPLICATION_ENV "development"
<Directory C:/xampp\htdocs/ZendSkeletonApplication/ZendSkeletonApplication-master/public>
DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
host entry at system32
127.0.0.1:8081 zf2-tutorial.localhost
How can i handle it.
Thanks
when you point with your apache document root to C:/xampp\htdocs/ZendSkeletonApplication/ZendSkeletonApplication-master/public
you need to use in your browser this url http://zf2-tutorial.localhost:8081/album
and not like you wrote http://zf2-tutorial.localhost/ZendSkeletonApplication/ZendSkeletonApplication-master/public/album
this url points internal to a different module/location.
//edit
if this not work check your zf2 /public folder if there is a .htaccess file present otherwise use the file from the zend skeleton application here https://github.com/zendframework/ZendSkeletonApplication/blob/master/public/.htaccess
please check also your apache vhost entry if the port is equal to your windows host file port.
make sure apache ModRewrite is loaded!
Basic misconfigurations in your setup causes this error.
I don't use windows for along time but you're using both forward and backslashes in your paths. Firstly, you should find the correct directory separator for windows and stick with it. This seems problematic: C:/xampp\htdocs/foo/bar/public
You're defining a virtualhost which listens any IP address on port 81 (*:81), a system32 hosts entry which points to port 8081 as zf2-tutorial.localhost alias and trying to call zf2-tutorial.localhost/album url using port 80. Getting this kind of error pretty normal.
After completely reading the official Getting Started and Using Apache Web Server documentations, you'll easily figure out the solution.
It seems you missing a vhost entry in your webserver. This could the reason why your application doesn't resolve your request right. Check the "getting startet: A skeleton application" again, to provide a proper configuration.
You need this hostfile entry. Adding ports is not possible in this file.
127.0.0.1 zf2-tutorial.localhost
The website is now available at zf2-tutorial.localhost:81 (and not 8081, you set 81 as the portnumber in the first line of httpd-vhosts.conf)
Starting a new project with the skeleton module and I'm running into some issues. I'm sure this is a basic config error on my part, but I can't figure it out.
Here is my module.config.php
return array(
'controllers' => array(
'invokables' => array(
'ZFTickets\Controller\Index' => 'ZFTickets\Controller\IndexController',
),
),
'router' => array(
'routes' => array(
'zftickets' => array(
'type' => 'Literal',
'options' => array(
// Change this to something specific to your module
//'route' => '/zftickets',
'route' => '/',
'defaults' => array(
// Change this value to reflect the namespace in which
// the controllers for your module are found
'__NAMESPACE__' => 'ZFTickets\Controller',
'controller' => 'Index',
//'controller' => 'ZFTickets\Controller\Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
// This route is a sane default when developing a module;
// as you solidify the routes for your module, however,
// you may want to remove it and replace it with more
// specific routes.
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'zftickets' => __DIR__ . '/../view',
),
),
and here is the directory structure:
The error I get is: Zend\View\Renderer\PhpRenderer::render: Unable to render template "zf-tickets/index/index"; resolver could not resolve to a file
The resolver is looking for zf-tickets/index/index, but you're created the folders as zftickets/zftickets/index. Change these and it should work fine.
You should also change the view manager part of your config to:
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
The array key is irrelevant there, so what you currently have might appear confusing.
ZF2's view renderer will try to render .phtml files accordingly matched controller/action names since you don't provide a custom template. Try to rename second zftickets folder to your controller name (in this case: index) like this:
|-- ...
|-- test
|-- view
| `-- zftickets
| `-- index
| `-- index.phtml
`-- autload_classmap.php
There are three modules in my app/modules/, named Application, Album, Shop. I want to access each of these modules using HOSTANME/application, HOSTNAME/album, and HOSTNAME/shop. For Application modules, the configuration is:
'router' => array(
'routes' => array(
'application' => array(
'type' => 'Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'AppliWcation\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController',
.........
),
},...
There are multiple Controllers under Application module. Via this method, I can accessed URL like:
http://www.myhostname.com/application/controllerName/actionName
It is the similar configuration for other two modules.
This works previous T61 thinkpad at beginning of last month. Then I reinstalled Php/apache in my new bought T410. I also git pull latest ZF2 version:
git log
commit 73e0de644789aa5b712c97f55c512c57c2b9ac76
Merge: 7c65991 d722da5
Author: Matthew Weier O'Phinney <matthew#zend.com>
Date: Fri Oct 4 11:01:06 2013 -0500
Merge branch 'hotfix/version-composer'
Fix for issue introduced with #5191
But everything does not work anymore. I checked the error.log:
[Sun Oct 06 10:47:05 2013] [error] [client 127.0.0.1] File does not exist: /path/to/app../ChipShop/public/application
However, it works for default route http://www.myhostname.com.
Is there any wrong in my configuration or some configuration rule has been changed? Thanks
[UPDATE]
There is similar post ZF2 routing configuration, I tried method:
'user' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/user',
'defaults' => array(
'controller' => 'Application\Controller\User',
'action' => 'some-action',
),
),
) ,
But it still not work for me..
SOLUTION
The issue is not in code side. It is in my confiuration.
1, I forgot to enable apache rewrite module. As what said in akond post.
2, In virtualHost confiuration,
AllowOverride None
should be changed to
AllowOverride All
https://github.com/zendframework/zf2 clearly states that the master branch contains 2.2.5dev. Dev releases are potentially unstable and you should not rely on them. Use composer with
"require": {
"zendframework/zendframework": "~2.2.0"
}
and you will be just fine.
Update
The error message says it cannot find the application directory. Of course it does not exist, since it is virtual. This means that problem is not in the ZF routes at all. Check that
.htaccess file exists in the public directory and is of correct content
Appache is configured to parse this .htaccess file
mod_rewrite module is on.
the directory up to your public directory does exist
and the Virtual Host is attached to this directory.
After searching a long time with no success.
before I give up, I would like to ask:
Is there a way to route a subdomain to a module in Zend Framework 2? like:
Subdomain => Module
api.site.com => api
dev.site.com => dev
admin.site.com => admin
site.com => public
...
I tried doing it like this but I can't get access to controllers other than the default (Index).
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'site.com',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
)
)
),
),
Thank you for taking the time to help me.
Zend Framework 2 doesn't have a notion of routing to modules; all routing mappings are between a URI pattern (for HTTP routes) and a specific controller class. That said, Zend\Mvc provides an event listener (Zend\Mvc\ModuleRouteListener) which allows you to define a URI pattern that maps to multiple controllers based on a given pattern, and so emulates "module routing". To define such a route, you would place this as your routing configuration:
'router' => array(
'routes' => array(
// This defines the hostname route which forms the base
// of each "child" route
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'site.com',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
// This Segment route captures the requested controller
// and action from the URI and, through ModuleRouteListener,
// selects the correct controller class to use
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Index',
'action' => 'index',
),
),
),
),
),
),
),
(Click here to see an example of this # ZendSkeletonApplication)
This is only half of the equation, though. You must also register every controller class in your module using a specific naming format. This is also done through the same configuration file:
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController'
),
),
The array key is the alias ModuleRouteListener will use to find the right controller, and it must be in the following format:
<Namespace>\<Controller>\<Action>
The value assigned to this array key is the fully-qualified name of the controller class.
(Click here to see an example of this # ZendSkeletonApplication)
NOTE: IF you aren't using ZendSkeletonApplication, or have removed it's default Application module, you will need to register the ModuleRouteListener in one of your own modules. Click here to see an example of how ZendSkeletonApplication registers this listener
If i understand slide #39 of DASPRIDS Rounter Presentation correctly, it's as simple as - on a per module basis - to define your subdomain hosts, i.e.:
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'api.site.com',
'defaults' => array(
'__NAMESPACE__' => 'Api\Controller',
'controller' => 'Index',
'action' => 'index',
),
)
)
),
),
Etc, you'd do this for every Module on its own.