I want to create an API to communicate with a REST Web Service.
For this, I'm building this API as a library. I Just create the folder structure:
├── composer.json
├── LICENSE
├── README.md
└── src
└── PkgRoot
└── PkgName
├── XXXAPIFactory.php
├── XXXAPI.php
├── XXXAPIRestImpl.php
├── XXXResponse.php
└── Protocol.php
Now, I'm trying add a configuration for the API-KEY. I believe this should be added in config.yml.
Should I change all these structure the be like a Symfony Bundle? How can I add and register configurations parameters in config.ym?
It is not mandatory, but I think that you definitely should. Why aren't you using a Bundle ?
Using a Bundle would permit you, among so many other cool things, to create a friendly configuration as you want.
Related
I have some Dashboard module.
Dashboard
├── Components
├── Policies
├── Queries
└── QueryScopes
└── UserActivity (this corresponds to component)
Dashboard\DashboardBuilder vs just Dashboard\Builder?
Dashboard\DashboardComponent (interface) vs just Dashboard\Component?
Dashboard\Queries\UserActivityQuery vs just Dashboard\Queries\UserActivity?
Dashboard\Policies\UserActivityPolicy vs just Dashboard\Policies\UserActivity?
What are some pros/cons?
What do you use?
Note:
I have tried to find out what convention is Laravel following but even there are some inconsistencies (Policies\PostPolicy but Query\Builder).
Structure of my project:
├── apps
│ ├── backend <= Micro
│ └── frontend <= Application
├── public
│ ├── css
│ ├── index.php <= Single entry point
│ └── js
└── vendor
├── ...
Note: I dont want use two entry point, something like this:
├── apps
│ ├── ...
├── www
│ ├── css
│ ├── index.php <= Entry point for Frontend
│ └── js
├── api
│ ├── index.php <= <= Entry point for Backend
It is still a spare option.
Question:
Tell me where I can see example of such project?
If chosen way of organizing the project is wrong, what is correct one?
In both cases, I would like to get an example code for the following files:
public/index.php // or www/index.php & api/public.php
apps/forntend/Module.php // or something similar
apps/backend/Module.php // or something similar
and how I should organize work with routes, dispatcher, etc.
You can employ different solutions for this. Yes you can do #Juri wrote for sure but if you want your API/Backend to be as slim as possible, then you can use the Micro application.
The trick is to have an abstract bootstrap class which performs all of your initializations (including the application object) and override this with the relevant bootstrap classes for frontend, backend, cli etc.
Have a look at the Phalcon website implementation, in particular the Bootstrap class on how you can achieve this.
The implementation is explained in length in these posts:
https://blog.phalconphp.com/post/building-the-new-phalcon-website-implementation-part-1
https://blog.phalconphp.com/post/building-the-new-phalcon-website-bootstrap-part-2
https://blog.phalconphp.com/post/building-the-new-phalcon-website-middleware-part-3
Why combine them? Just use Phalcon\Mvc\Application alone. Micro doesn't even have dispatcher, modules etc. Phalcon\Mvc\Micro is seperated thing and it shouldn't be used in same application where Phalcon\Mvc\Application.
What exactly you want to achieve?
I have an old application running on top of Zend Framework 1 (ZF1), I'm starting a Symfony3 (SF) migration so I have managed with some .htaccess rules to make Symfony3 work inside the ZF1 application. Basically if I call a Symfony route it goes to Symfony controllers otherwise goes to ZF1 controllers.
I need to use ZF1 session data in the SF controller but the ZF1 Session and SF Session works completely in different way so calling ZF1 Session from the SF won't work. (I've already test it).
What comes to my mind then was save the same data to both session objects: the ZF1 used all over the legacy application and the SF used on the new controllers so I end up with something like this:
// The following goes to an special ZF1 storage managed through Session
$this->view->user = Zend_Auth::getInstance();
$result = $this->view->user->getStorage()->read();
// This is a Symfony\Component\HttpFoundation\Session\Session
$session_1 = new Session(new PhpBridgeSessionStorage());
$session_1->start();
$session_1->set('result', $this->view->user->getStorage()->read());
// here $session_1 holds the values properly
$session_1->get('result');
The Symfony session is configured as follow:
session:
handler_id: session.handler.native_file
save_path: '%kernel.root_dir%/sessions'
Then in my Symfony controller I am trying to access the stored data as:
$session = new Session();
$result = $session->get('result');
But the value of $session->get('result') is null and as far as I know it shouldn't be empty. I don't know if the directory structure is responsible for this issue or what I am doing wrong or maybe is simple and this is not possible at all because the Session() objects instances are different due to the directory structure.
This is how the directories are structured (weird but is the only way I did found so far to make this work):
├── application
│ ├── api
│ ├── controllers -> ZF1 controllers
│ ├── forms
│ ├── layout
│ ├── models
│ ├── soap
│ └── views
...
├── oneview_symfony -> this is the SF app
│ ├── app
...
│ ├── var
│ ├── vendor -> it has his own /vendor folder and a /symfony libraries
│ └── web
...
└── vendor
...
├── symfony -> /symfony libraries are here as well
...
├── zendframework
Update
Didn't tried before but now following #bishop suggestion I have bridged the Symfony session with ZF1 session (or at least I think I did) by adding the following:
session:
storage_id: session.storage.php_bridge
handler_id: session.handler.native_file
save_path: '%kernel.root_dir%/sessions'
But it doesn't work either, the error is same as before result gets null.
Any clues? Ideas?
I agree with #bishop and you correctly bridged the session, but I believe your problem is different. My assumption is that your session save_path is not shared between the Zend and Symfony applications.
You have to use the same path for this to work.
Try setting:
phpSettings.session.save_path = "/path/to/symfony/kernel/root/sessions"
in your application.ini of the Zend framework application.
Replace with your sessions path.
I'd like to make my first large project in php. I use Phalcon PHP and I created project structure using Phalcon Developer Tools. It something like:
.
├── app
│ ├── cache
│ ├── config
│ │ ├── config.php
│ │ ├── loader.php
│ │ └── services.php
│ ├── controllers
│ ├── migrations
│ ├── models
│ └── views
├── index.html
└── public
├── css
├── files
├── img
├── index.php
├── js
└── temp
I think i'll need some global function and classes. I'd like to implement for example Laravel's dd function to dumb variables and using this function like
dd($value);
wherever i want. I also want to create some global classes to use theirs static functions. For example:
User::isLogged()
How to implement this in my project? Create directory functions or lib or indcude in app/? Is it a convention? Place global classes in individual folders? How to separate global functions and classes and register those in standard Phalcon loader and do it once for whole project?
Good thing about Phalcon is that you have the freedom to organize your project in the way it best fits your current situation.
A more general approach I'm using in most of my projects is to register the most used namespaces in the autoloader. In my case I'm using multi module structure and this is done in the Module.php file for the given module.
Module class:
class Module
{
public function registerAutoloaders($di)
{
$config = $di->getConfig();
$loader = new \Phalcon\Loader();
$namespaces = [
'Frontend\Controllers' => __DIR__ . '/controllers/',
'Frontend\Forms' => __DIR__ . '/forms/',
'Models' => $config->site->path->common . 'models/',
'Helpers' => $config->site->path->common . 'helpers/',
];
$loader->registerNamespaces($namespaces);
$loader->register();
}
}
Helpers in my case are files which are not models and serve for something specific. For example I have a Files helper which holds functions for manipulating the file system. I've got a Helper for handling string operations like slugalization, latinization and so on...
I've also have a Lib folder in which I put my public libraries like PHPMailer, BrowserDetect, ImageProcessing libraries and so on.
And now about the global functions like Laravel's dd(). I have a small file which I include in the bootstrap file or your index.php. It contains 1-2 global functions like:
function d($what)
{
echo '<pre>';
print_r($what);
die('</pre>');
}
In my case there are not that many global functions which I want to use everywhere easily, like above one for debugging. Rest of the stuff I've put in the Helper files mentioned above.
Hope I helped and would be glad to hear someone else's opinion on this.
I am trying to make a view on my package, and this is my code:
View::make("User::login");
But I get this error: No hint path defined for [User].
My structure is like this:
app
├──config
├──database
├── modules
└── Core
└── User
├──Controllers
├──models
└──views
└──login.blade.php
├── lang
├── migrations
└── routes.php
The view namespaces actually have nothing to do with PSR-4. You also have to add view directories manually. You can either do that by adding it to the paths array in config/view.php or by registering it somewhere else (preferably in a service provider)
View::addLocation('/path/to/views');
To come back to your actual question, you can register view namespaces like this:
View::addNamespace('User', '/path/to/views');
i've resolved my problem.
it was my fault, it should be :
View::make("Core/User::login");
thanks.