How to use the 'raw' PHP Mongodb PECL driver within Symfony2 [duplicate] - php

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Using Imagick in Symfony2?
I'm new to Symfony so this might be a dummy question. But since after several hours of google I haven't found any related answer it might worth a try here.
So basically I was using Windows, Apache, pure PHP, Mongodb and the 'raw' PHP_Mongodb PECL driver (the word 'raw' is used here to differ from the Doctrine Mongodb ODM bundle in Symfony2) for web application development. The PECL driver worked perfectly fine, and I could just write something like this:
<?php
$m = new Mongo();
$db = $m->myDB;
$db->find();
//Do Other DB Operations.
The above code worked fine without any 'use', 'include' or 'require' statements since I followed the standard instructions and setup the PECL driver extension in php.ini. When showing phpinfo() in the web browser, the Mongodb driver information shows up correctly. Everything's perfect.
Then I start to use Symfony2 because it provides url rewriting, MVC pattern, security and other useful stuff. The Doctrine Mongodb ODM bundle works nice except that, seems to me, it can only persist PHP objects. I do have a bunch of javascript object in my project to persist and there is simply no way of doing that except to put a 'PHP wrapper' on top of it (to create a PHP object which contains only that javascript object).
When I was trying to use the good old PECL trick to talk to the database with the same block of code above, I got this error:
Fatal error: Class 'MyProject\Controller\Mongo' not found in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\Symfony\src\MyProject\Controller\DefaultController.php on line 47.
Seems Symfony2 blocked or overwrited the extension paths in php.ini while only looking for its auto class loader. I guess I'll need to change the autoload.php and/or AppKernel.php to include that extension? Please help me understand what's going on here. Can I use the PECL driver in Symfony2 at all? Or is Doctrine Mongodb ODM the only way to access database in Symfony2? Thanks!

Symfony2 works with namespace php. This makes working with non-namespace libraries/classes a bit tricky, but you really just need to know the tricks.
When you try to use new Mongo() to grab a mongodb object, PHP looks in your current namespace, which means it looks for a mongo() function within your class. To make this work, you need to specify the namespace for mongo. Since it does not use namespaces, PHP places it in the global namespace . So, to correctly reference the function, you need to use new \Mongo(), and PHP will look in your \ namespace instead of your current one.

Related

Prestashop 1.6, conflict: 2 different modules requiring same class, different versions

In my Prestashop project, I have several modules. In one of them (let's call it "AWS") I installed AWS SDK using composer (in PHPStorm), as explained here. Composer has "required", among other libraries, "guzzlehttp", updated to its final version.
On the other hand, there is another module (let's call it "orangeConnect") with composer too, that has an earlier version of "guzzlehttp".
The problem lies when I am using AWS SDK in php, inside a php script in the first module. What happens is that it tries to call the URI Composer class and it crashes. Actually, because of the inexistence of one class "UriResolver". The thing is that if I remove "orangeConnect" then AWS SDK connect correctly, which means that the class Uri, in "AWS" is not taken correctly because of "orangeConnect" module. However, I need imperatively to support "orangeConnect" in the project.
How can I, in summary, solve this conflict between classes in PHP inside Prestashop and allow each module to include the corresponding valid version of guzzleHttp without conflicts of any kind?
Thank you.
If the official maintainer of orangeConnect module doesn't upgrade the code, there are only 3 methods you can take:
Method 1: You can maintain a copy of your own orangeConnect code, and upgrade to latest Guzzle. Usually it won't be to difficult because Guzzle's interface are well designed.
Method 2: Get the old Guzzle's code and put it into a new namespace (eg: OldGuzzle) and make orangeConnect use OldGuzzle namespace. You can achieve this by do a global regex replace simply.
Method 3: (Only for big systems) Divide your PHP application to micro-service modules, and isolate orangeConnect and AWS SDK and make them use different Guzzle.

Config files in a custom Symfony compatible library

Ok, so I am working on creating a custom standalone library that I intend to use in a Drupal 8 site. Drupal 8 runs on Symfony 2.8.x. I want this code to be usable outside Drupal. So I have focused on making it more Symfony oriented than Drupal oriented.
What I have found, thus far, with all my searching, is that Symfony requires you to write a bunch of config declarations in DependencyInjection/Configuration.php. As well as service declarations in a MyBundleExtension.php file.
What I have NOT found is a simple way to say "Hey, I want this config parameter in this standalone (not at all a controller) class". So I wrote the class you see below.
Is there a better way to handle this?
Code: http://pastebin.com/pdp53kxe
Also, will this create any problems with loading services?
At some point I have to deal with dependency injection and actually new up what we want to inject. Still not sure how I will work that into this standalone library while utilizing the Symfony framework. So suggestions as to how to have Symfony wire that up for me would be great.
My basic question here is about using Symfony in a library setting. Where you would not expect to just need the variables within a controller context.
Like you said if you want to import configuration you need to use your DependecyInjection/MyBundleExtension.php class to load the config (maybe even parse) yourself.
Another way is to use compiler passes to directly manipulate the container but this looks like it would be an overkill for your case.
The main reason is that the Dependency Injection Container (wich contains all your service definitions and config parameters) is compiled.
So you have to inject your extra config before the compilation.
Helpful links:
http://symfony.com/doc/current/service_container/import.html
http://symfony.com/doc/current/service_container/compiler_passes.html

Composer: two libraries class name conflict

I am using these two libraries from composer
"require": {
"alterfw/php-form-generator": "^0.1.2",
"rlanvin/php-form": "dev-master"
},
Biggest issue is both has the same class name Form with no namespace defined. Now no matter either I am instantiating only one class or both on the same page it is giving me an error as below
Fatal error: Call to undefined method Form::create() in...
create method is to generate form markup from alterfw/php-form-generator library.
So when I tried this
$form = Form::create('path-to-action.php');
$form->add(Form::text('settings')->setLabel('Settings')->setValue('None'));
echo $form->render();
Giving me the error mentioned above. For me it is difficult to understand why even I hven't instantiate another class it is still giving error.
I a also not so much familiar with composer to dig into myself without any guide.
So is there any way so I can use both libraries at the same time?
Tip: Packages without a vendor namespace are a bad practice, as you can see here. I recommend creating an issue for both packages saying they should really add a vendor namespace.
The problem here is that as soon as you use Form in your code, the class isn't already loaded and Composer's autoloader is executed. As it has 2 packages to load the class from, it'll pick the first registered autoload rule. This results in the wrong Form class: Problem!
You can swap the packages position in your composer.json, but this means the other class is no longer usable.
Another solution is to require the class yourself by using the require()/require_once() PHP functions. This is a bad practice and also means you can only use one of the 2 Form classes (requiring the other form class after one is already required results in a "Class with name "Form" already exists" PHP error).
TL;DR: You can only use one of the 2 packages in the same application.
There is really no shortage of form validation libraries. Every single framework should have one component for this.
So I'd recommend selecting your libraries carefully.
We have here the first library "alterfw/php-form-generator", which is 4 years old, being unmaintained since then, until it got forked 4 months ago with adding composer.json. Four years ago, PHP 5.2 was still common, so it is no real surprise that this code has no namespace. It also has no real documentation, because the link in the readme file is dead. The forked repository of this library does not allow creating issues. :( I doubt that the upstream repository will care about anything after 4 years of not maintaining it.
The second library "rlanvin/php-form" seems to be tied to non-public code. You opened a ticket to add namespace to that one class, and effectively got rejected (saying that the maintainer will not add namespaces because it is more convenient for him, but you could edit the file yourself to add it simply does not cut it). Packagist shows that this library has 31 installs. It's not completely right to say that "nobody uses this code", but it is very close.
If your task is form validation and form generation, I'd say that either the Symfony or Zend components will likely perform that task very well. There probably is no need to resort to libraries that "nobody" uses, and that do not apply modern development methods like namespaces (available since PHP 5.3, which was released in 2009).

Cleaning a Symfony project and installing a new bundle

Im very new to Symfony, yet Im already familiar to the MCV model, after a while reading the documentation I have now the standard edition of Symfony 2 running on my server.
Fresh start
As you know Symfony comes with a hello world app and some welcome scripts, how can I clean all of that?, even better, is there a way to install a Symfony project without the examples bundles?
Data base structure restore
In the past, every time I developed an app with database, I created the structure of the tables using phpmyadmin and then an initial php script that restore that database if I need to install my app on other server. Working with Symfony is quite different, I read that it use doctrine and the Symfony core restore the database format using some internal files. I have a bundle that I need to install, I know that this bundle/app use MySQL, I set the config file with all my MySQL information but I dont know how I can run a sript that will restore a clean database needed for that particular app. I know it has something to do with php app/console schema:update but not so sure.
Thanks for any orientation.
how can I clean all of that?, even better, is there a way to install a Symfony project without the examples bundles?
There is no way to do that in Symfony2 and it looks like it never become a part of the Symfony2 project:
"I think that we need clear instructions on how to remove the Acme demo code by hand. I'm -1 on added a CLI command to do that automatically."
-- fabpot on github
The things you should do:
Remove the src/Acme directory
Remove $bundles[] = new Acme\DemoBundle\AcmeDemoBundle(); (line 25) in app/AppKernel.php
Remove the related routes from app/config/routing_dev.yml (_welcome, _demo_secured and _demo)
You can remove everything in the security: key in app/config/security.yml and place enabled: false in it. However, this isn't needed and it works like a nice boilerplate for your own security
Your other question: Symfony2 don't have a 'view' layer. You can choose to use whatever you want. But Symfony2 included 2 ORMs in their framework by default, Doctrine and Propel. You can read more on how to work with these libraries in the documentation: Doctrine and Propel.

Error with Propel and ZendFramework

After inheriting some Zend Framework code it didn't work, after lots of fiddling I've managed to create the schema and rebuild the models, although now I'm getting the following error:
Call to undefined method Criteria::hasSelectClause() in home/richard/library/om/BaseDomainPeer.php on line 329
Why would propel generate files that call unknown methods?
I would think that you have a name collision and you load some other class called Criteria and you don't realize it because of autoloading. Try dumping the methods using get_class_methods()
Turns out the code was built on a system using the beta version of propel, when i forced my system to use the beta version, it worked.
to use the beta version, go here

Categories