Cakephp 3: React/zmq library namespace - namespaces

I am working on on the basic tutorial on using ratchet mentioned here http://socketo.me/docs/push.
I have created a test setup for the tutorial that works flawlessly. However, when I am trying to integrate the setup with CakePHP 3 I am running into problems. The ratchet and ZMQ servers are independent just the way mentioned in the tutorial. Only the following piece of code needs to move into CakePHP 3 controllers:
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://localhost:5555");
$socket->send(json_encode($entryData));
This code basically submits new data to ZMQ queue for forwarding to ratchet. If I place the same 4 lines in a plain PHP file outside CakePHP 3 codebase it works. When I place the same four lines inside APP\Controller\SamplesController it says the class APP\Controller\ZMQContext not found.
CakePHP 3 docs mention that vendor libraries installed via composer will be automatically available through autoloader. I have installed React\ZMQ library via following command:
php composer require react/zmq
I have tried accessing the class via following namespaces but none of them have worked:
ZMQContext ( Class 'App\Controller\ZMQContext' not found )
\ZMQContext ( Class 'App\Controller\ZMQ' not found )
React\ZMQ\ZMQContext ( Class 'App\Controller\React\ZMQ\ZMQContext' not found )
\React\ZMQ\ZMQContext ( Class 'React\ZMQ\ZMQContext' not found )
Probably missing out on some namespace concept in PHP but my understanding is that if ZMQContext is available in a normal PHP file through global namespace, then it should also be available within CakePHP 3 via \ZMQContext.
I have following questions:
How can I push data to ZMQ Queue within my CakePHP 3 APP ?
APP::path() & APP::classname() seems to work only for classes within the CakePHP 3 application. How to check path for a particular vendor library class ?
How to autoload vendor library classes correctly ? (I do not wish to require/require_once them as it will needed to be done for each controller that wants to publish data via ratchet)
Is the assumption about accessing global namespace via \CLASSNAME wrong ?
My second attempt at accessing vendor library class at \ZMQContext resolved to App\Controller\ZMQ. How is that possible when it should have attempted within root namespace ?
ZMQContext is not part of react/zmq library so does it mean it part of default php bindings for libzmq ?

This was a simple typo problem:
$context = new \ZMQContext();
$socket = $context->getSocket(\ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://localhost:5555");
$socket->send(json_encode($entryData));
The second namespace specification in second line was missing.

Related

How to have class loaded without using "use" but call it as if I used it

I have studied these 2 sources, but none of those works for me.
http://www.yiiframework.com/doc-2.0/guide-concept-autoloading.html
Yii2 - How do I AutoLoad a custom class?
I have created custom helper class which I want to include in every model, controller and view in my application. I am using Yii2 advanced app version 2.0.11, IDE I am using is PHPStorm
QUESTION:
What I want to achieve is to not use use keyword at the beggining of every class but still be able to simply call AppHelper::myMethod() in models, controllers and views.
How is that possible?
Closest I got it working was using this solution https://stackoverflow.com/a/35160997/5395463
All other solutions did not work for me. I am getting errors like:
PHP Fatal Error – yii\base\ErrorException
Class 'frontend\controllers\AppHelper' not found
when I simply dont include use commons\commands\AppHelper;
or when not using namespace as they suggest there with other settings:
Fatal error: Uncaught exception 'yii\base\UnknownClassException'
with message 'Unable to find 'common\commands\AppHelper'
in file: C:\xampp\htdocs\domain.com\web\common/commands/AppHelper.php.
Namespace missing?' in ...
SOLUTION:
Thanks for your responses, I got it working finaly. https://stackoverflow.com/a/42330631/5395463 solution works best for me.
So I removed namespace from that class, but left it in common\commands folder, added require to frontend/web/index.php and backend/web/index.php files (not sure if I should add it to yii file in root too, I didnt, so far it is working good anyways), and changed calls of class from AppHelper::myMethod() to \AppHelper::myMethod() looks like eveything is working now.
In Yii2 You can use an explicit way adding \ to full namespaced name
\frontend\controllers\AppHelper
so you can sue your method
\frontend\controllers\AppHelper::yourMethod();
Solution for not lazy coders:
create component with your class so you can use it like \Yii::$app->my_component
if even this is too much and your IDE is better than Windows Notepad prepare macro that will print this for you
Solution for lazy coders:
Save your class in single PHP file without namespace.
Modify you entry script to include this class - i.e. for Basic Project Template it's /web/index.php; add there
require(__DIR__ . '/path/to/MyClass.php');
For Advanced Project Template modify it properly.
Now you can use your class by calling it like \MyClass (yes, \ is required and yes, your IDE probably will modify it anyway to MyClass with use MyClass; added at the beginning.

Namespace in php application

I am trying to manage my code in a sample code to learn. I have a sample application whose dir structure is as follow
-Sample
--bootstrap
--app
--class1.php
--class2.php
--class3.php
--config
--public
--resource
--readme
Everything works fine for me, able to autoload the classes and consume all the feature.
Now, I added namespace to my class definition.
namespace Sample\classes;
and my application won't work. In app needs I am trying to add
$obj = new Sample/classes/class1() //no class found
use Sample/classes as Sample
but still class not found error
Any help to consume namespace in this setup will be appreciated.
You need use backslash instead of slash
$obj = new Sample\classes\class1()

Grails package change for domain class caused DuplicateMappingException

While working through a tutorial to start learning Grails, I made a mistake and ran:
grails create-domain-class com.FooBar
instead of:
grails create-domain-class com.acme.FooBar
It was immediately obvious I had made an error so I tried the following:
Searched for a function that reverses the create-domain-class command, it seems there isn't one.
Searched for advice on the web and the consensus is that you can delete a domain class file, any associated views and tests, then to be safe run a text search for your class name in your project directory for any references you may have missed. I have done all this.
Then I ran the correct command to create com.acme.FooBar, which worked.
After this the app fails to run and reports the following error:
org.hibernate.DuplicateMappingException: duplicate import: FooBar refers to both com.acme.FooBar and com.FooBar (try using auto-import="false")
After adding the following code to com.acme.FooBar:
...
static mapping = {
autoImport false
}
...
The app now runs as expected.
However as an experienced Java developer who occasionally does refactor a package I would like to understand how to do that without causing a DuplicateMappingException or resorting to the "autoImport false" solution.
Thanks.
You shouldn't be doing
static mapping = {
autoImport false
}
As, by doing this you said that don't check for domain just by name and look up for package as well. Hence, once you do that you will have to use Fully qualified name of the class in your queries / hqls which may itch sometimes.
You should be removing the Domain completely i.e.
remove the Domain
remove the view folder creating by default with very same name and so do the controller
Now, do grails clean-all(Make it a thumb rule to use grails clean-all first for any issue unexpectedly occuring).
To be more accurate do remove target directory from your project and then do run grails run-app.
I had done very same thing many times and got it resolved by above steps.
Hope it helps.

Yii2 access to actions in new controllers

Comrades, I have had issues implementing yii2 basic but I'm yet to give up. I have successfully installed yii2, activated pretty url and created the .htaccess file in the root folder. The Home, About, Contact and Login urlswork fine.
i. I have created a new model, InstTypes with the CRUD. Why does http://localhost:8081/we#ss/instTypes/create return Not Found (#404)?
ii. I have also created a module instClients. I can access the index action in the DefaultControler. I have a model Insts with its CRUD under this modules. Why does http://localhost:8081/we#ss/instClients/insts/create return Not Found (#404)?
I tend to think that this could be due to the removal of the import and autoload from the config.
Could someone demonstrate how they've created a new model and CRUD and successfully accessed its actions?
Thanks in advance
I have created a new model, InstTypes with the CRUD. Why does
http://localhost:8081/we#ss/instTypes/create return Not Found (#404)?
You cannot access a model directly, the only way to interact with a model is via a controller which will intern interact with the model and the view. By initializing the model $model = new YourModelNmae(); or by rendering a view.
From your URL
http://localhost:8081/we#ss/instTypes/create
InstType should be your controller while create is an action under InstType
Using Yii2 Gii tool to generate a CRUD do the following : -
Generate your model
Generate your CRUD
go to
http://localhost:8081/we#ss/yourController/YourActionOnYourController
Refer to this youtube link for more detail https://www.youtube.com/watch?v=6B52-li6IgU
Happy coding :)
Just to add to the other answers, your url isn't working because it's camelCase. You need to make it hyphenated, so
http://localhost:8081/we#ss/instTypes/create
will become
http://localhost:8081/we#ss/inst-types/create
You're getting the 404 because you're trying to access instTypes, it should be inst-types.
this solved my problem. I needed to add the controllers to the controller map.

Why aren't namespace autoload classes loading in phpunit tests?

To compliment an existing smorgasbord of arrangements between phpunit,autoload and namespace is this:
I have created a simple test project that runs PhpUnit tests and uses namespace autoloading. I register the autoloading in the bootstrap file like so:
set_include_path(get_include_path() . PATH_SEPARATOR . "/path/to/classes/folder");
spl_autoload_register();
and inside a unit test I load and test my class like so:
$obj = new \some\space\someClass(); // which is in the classes/some/space folder
$this->assertTrue($obj->foo()=='bar');
And I get an error
Fatal error: Class '\some\space\someClass' not found in testSomeClass.php...
While this is not phpunit specific you need to change:
spl_autoload_register();
to
spl_autoload_register('spl_autoload');
Any other component that registers an autoloader unregisters the default __autoload().
If your code has an existing __autoload function then this function must be explicitly registered on the __autoload stack. This is because spl_autoload_register() will effectively replace the engine cache for the __autoload function by either spl_autoload() or spl_autoload_call().
So this is how spl-autoload works together with anything else that uses autoloading.
Make sure your path to classes folder is made relative to script which is run for tests execution. If the script is in subfolder of your projects (for example tests/) then your path should be ../path/to/classes/folder
That's what I have in my tests/bootstrap.php
set_include_path(dirname(__FILE__).'/../classes'.PATH_SEPARATOR.get_include_path());
spl_autoload_extensions('.php');
spl_autoload_register('spl_autoload');