I've migrated my Phalcon project from 2 to 3 and get some unexpected behavior. In my loader I do this:
<?php
use Phalcon\Loader;
$loader = new Loader();
$loader->registerDirs(
array(
$config->application->libraryDir,
$config->application->controllersDir,
$config->application->modelsDir
)
);
$loader->register();
Now, when I try to instantiate one of my models in my controller-action the code halts:
$present = new \Present();
Results in a "recv() failed (104: Connection reset by peer) while reading response header from upstream" error in /var/log/nginx/error.log.
However, when I instantiate the class directly in my loader.php file the model is auto-loaded and I can instantiate it anywhere. The workaround for the controller action is:
if (class_exists('Present')) { // THIS triggers the autoloader
$present = new \Present();
$present->save();
}
So the issue is solved for now. My question is: why doesn't
new \Present()
trigger the auto-loader in the controller-action as I expected? Why did it work under Phalcon 2? Why does it work when I do it directly in the loader.php or in public/index.php?
Related
I'm trying to create an API with Phalcon for the first time.
I have been followed the tutorial "http://docs.phalconphp.com/en/latest/reference/tutorial-rest.html", but encountered a problem.
I've been created a new project with all the settings, and inside I got:
a "models" folder with "photos.php" file
a "index.php" with connection to my DB and function to retrieve information from "photos" table
The problem is that when I'm trying to activate the function through the browser i get an Error:
"Phalcon\Mvc\Model\Exception: Model 'photos' could not be loaded inC:\wamp\www\Test\index.php on line 77".
$photos = $app->modelsManager->executeQuery($phql); // line 77
What can cause this problem?
It's one of three problems:
1 - Your class name in photos.php is not photos.
2 - You have mis-referenced the photos model in your PHQL query.
3 - You have not registered the directory where your models are stored. To do this, add
$loader = new \Phalcon\Loader();
$loader->registerDirs(array(
'/path/to/models'
))->register();
after
$di = new \Phalcon\DI\FactoryDefault();
but before
$app = new \Phalcon\Mvc\Micro();
If you create project structure using Phalcon developer tool, the config.ini might need an update like this:
from:
modelsDir = /models/
to:
modelsDir = **..**/models/
i just faced same issue, got it solved by add require with model path right after $di = new \Phalcon\DI\FactoryDefault(); and
before $app = new \Phalcon\Mvc\Micro($di);
like suggested by brian
I'm trying to use FirePHP with Zend Framework 2, but there seems to be something missing. Here's the basic code I'm trying to run:
$writer = new Zend\Log\Writer\FirePhp();
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('FirePHP logging enabled');
The error I get is "FirePHP Class not found". I was initially puzzled because I do have a FirePhp class in my Zend/Log/Writer folder. But then I saw that the class constructor requires a FirePhp\FirePhpInterface object. So I checked the Zend/Log/Writer/FirePhp folder and there's a FirePhpBridge class in there that implements FirePhpInterface, but it also requires a FirePHP instance in the constructor. I don't have any FirePHP.php file in my Zend/Log/Writer/FirePhp folder. Am I supposed to get this from somewhere else?
Update
I now have managed to get FirePHP working, but I'm trying to figure out how to do it in a clean way so this works. The only way I've gotten it to work is putting it in the root directory of my project and doing the following:
include_once('FirePHP.php');
$writer = new Zend\Log\Writer\FirePhp(new Zend\Log\Writer\FirePhp\FirePhpBridge(FirePHP::getInstance(true)));
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('FirePHP logging enabled');
I assume that normally I should be able to create a writer like so:
$writer = new Zend\Log\Writer\FirePhp();
However, where this goes wrong I believe is in the getFirePhp() function of the Zend\Log\Writer\FirePhp class. The class does this:
if (!$this->firephp instanceof FirePhp\FirePhpInterface
&& !class_exists('FirePHP')
) {
// No FirePHP instance, and no way to create one
throw new Exception\RuntimeException('FirePHP Class not found');
}
// Remember: class names in strings are absolute; thus the class_exists
// here references the canonical name for the FirePHP class
if (!$this->firephp instanceof FirePhp\FirePhpInterface
&& class_exists('FirePHP')
) {
// FirePHPService is an alias for FirePHP; otherwise the class
// names would clash in this file on this line.
$this->setFirePhp(new FirePhp\FirePhpBridge(new FirePHPService()));
}
This is where I get lost as to how I'm supposed to set things up so that this class_exists('FirePHP') call finds the right class and new FirePHPService() also works properly.
First you should add this code to Module.php of your module
return array(
//...
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
);
and here content of autoload_classmap.php
<?php
return array(
'FirePHP' => realpath(APPLICATION_PATH . '/vendor/FirePHP').'/FirePHP.php',
);
FirePHP.php(renamed from FirePHP.class.php) downloaded from official site.
then you can write below code in any place of your module and it will work
use Zend\Log\Writer\FirePhp;
use Zend\Log\Logger;
$writer = new FirePhp();
$logger = new Logger();
$logger->addWriter($writer);
$logger->info("hi");
Am I supposed to get this from somewhere else?
Yes, you need to get FirePHP into your project and autoloading.
If you're using composer (and I recommend that you do), just add:
"firephp/firephp-core" : "dev-master"
(or similar) in your composer.json and update. If you're not using composer, you should grab the firephp libs, and let your autoloader know about them.
I'm pretty much newbie in Zend Framework action helpers and I am trying to use them with no success (I read a bunch of posts about action helpers, including http://devzone.zend.com/article/3350 and found no solution in like 8 hours). I used Zend Tool to setup my project and the name of the helper is Action_Helper_Common. No matter what I do, I get following error "Fatal error: Class 'Action_Helper_Common' not found". Currently, I have things set up like this:
zf version: 1.11.3
helper name: Action_Helper_Common
helpers location:
/application/controllers/helpers/Common.php
In Bootstrap.php i have following function:
protected function _initActionHelpers() {
Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH . '/controllers/helpers', 'Action_Helper');
Zend_Controller_Action_HelperBroker::addHelper(
new Action_Helper_Common(null, $session)
);
}
I also tried this without success (it was defined in Bootstrap.php before _initActionHelpers):
protected function _initAutoloader() {
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH . '/controllers/helpers'));
return $moduleLoader;
}
So what am I doing wrong?!?! PLZ help, I am desperate and about to give up :)
You got error because you haven't setup autoloader for Action_Helper_*
Resource autoloader
Helper broker uses plugin loader to load helpers based on paths and prefixes you specified to it. That is why ::getHelper() can find your helper
you dont need to do (so remove it)
Zend_Controller_Action_HelperBroker::addHelper(
new Action_Helper_Common(null, $session)
); ,
since you already did
Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH . '/controllers/helpers', 'Action_Helper');
when you will do
$myhelper = $this->getHelper('Common');
in your controller zf will lookinto directory /controllers/helpers/ for class name Action_Helper_Common and create an instance for you and return it.
For some reason the following line didn't work for me as well:
Zend_Controller_Action_HelperBroker::addHelper( new Action_Helper_Common() );
I just keep getting a 'Class not found' error each time I'm creating a new helper object explicitly.
This is what works for me:
Zend_Controller_Action_HelperBroker::getHelper('Common');
In this case, new Action_Helper_Common object gets created and is registered with Helper Broker.
Not sure though if it works for you, since you have a parameterized constructor.
I'm just getting to grips with Doctrine, and using the suggested lazy loading of models. As per the tutorials, I've created a doctrine bootstrap file:
<?php
require_once(dirname(__FILE__) . '/libs/doctrine/lib/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));
$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE, true);
$manager->setAttribute(Doctrine_Core::ATTR_MODEL_LOADING, Doctrine_Core::MODEL_LOADING_CONSERVATIVE);
Doctrine_Core::loadModels(array(dirname(__FILE__) . '/models/generated', dirname(__FILE__) . '/models')); //this line should apparently cause the Base classes to be loaded beforehand
My models and base classes have all been created by Doctrine.
I've also created a simple test file as follows:
<?php
require_once('doctrine_bootstrap.php');
$user = new User();
$user->email = 'test#test.com';
echo $user->email;
However, this generates the following error:
Fatal error: Class 'User' not found in E:\xampp\htdocs\apnew\services\doctrine_test.php on line 4
However, if I explicitly require the BaseUser.php and User.php files, then it works fine without any errors
<?php
require_once('doctrine_bootstrap.php');
require_once('models/generated/BaseUser.php');
require_once('models/User.php');
$user = new User();
$user->email = 'test#test.com';
echo $user->email;
So, it seems that Doctine is not auto loading the models correctly. What am I missing?
OK, so you need the following line in the bootstrap file:
spl_autoload_register(array('Doctrine_Core', 'modelsAutoload'));
And then auto loading works as expected
Your approach is correct since Doctrine has it's own loading functionallity:
Doctrine::loadModels('models');
Doctrine::loadModels('models/generated');
Doctrine::loadModels('models/tables');
...
This is not recursive so you need to add folders that contain your mapped/managed models.
In the User.php model there needs to be a require to the BaseUser.php class at the top. As the user class extends the BaseUser.php
I have had this issue and that has solved it. I would be interested if there is something I am missing to not have to do that include manually. Give that a shot and see if it fixes the issue without having to require the User.php
i setup Doctrine 1 b4 but it seems like now when i try Doctrine 2 it fails
i have Doctrine installed at D:\ResourceLibrary\Frameworks\Doctrine
D:\ResourceLibrary\Frameworks\Doctrine\bin
D:\ResourceLibrary\Frameworks\Doctrine\Doctrine
D:\ResourceLibrary\Frameworks\Doctrine\Doctrine\Common
D:\ResourceLibrary\Frameworks\Doctrine\Doctrine\DBAL
D:\ResourceLibrary\Frameworks\Doctrine\Doctrine\ORM
i put D:\ResourceLibrary\Frameworks\Doctrine\bin in the PATH Windows Environment Variable
and added D:\ResourceLibrary\Frameworks\Doctrine to the php.ini include_path
i find that when i try to do
D:\>php doctrine.php
Could not open input file: doctrine.php
fails ... i thought that since i have D:\ResourceLibrary\Frameworks\Doctrine\bin in the PATH Windows Environment Variable, it shld be able to find doctrine.php?
D:\ResourceLibrary\Frameworks\Doctrine\bin>php doctrine.php
Warning: require(D:\ResourceLibrary\Frameworks\Doctrine\bin/../lib/vendor\Symfony\Components\Console\Helper\HelperSet.ph
p): failed to open stream: No such file or directory in D:\ResourceLibrary\Frameworks\Doctrine\Doctrine\Common\ClassLoad
er.php on line 143
Fatal error: require(): Failed opening required 'D:\ResourceLibrary\Frameworks\Doctrine\bin/../lib/vendor\Symfony\Compon
ents\Console\Helper\HelperSet.php' (include_path='D:\ResourceLibrary\Frameworks\ZendFramework\library;D:\ResourceLibrary
\Frameworks\Doctrine;.;c:\php\includes') in D:\ResourceLibrary\Frameworks\Doctrine\Doctrine\Common\ClassLoader.php on li
ne 143
then 2nd try, pass with errors ...
After spending several hours to configure Doctrine 2 on my machine last night I finally succedded to work with Doctrine 2.
I configured Doctrine 2 in this way.
There are several ways to install Doctrine 2 although I preferred to download from package manager.
First I downloaded package DoctrineORM-2.0.0BETA3.tgz from http://www.doctrine-project.org/projects/orm/download
I extracted the tar file inside my test folder where I tested my sample code. My folder looks like
./test
DoctrineORM/
DoctrineORM/bin
DoctrineORM/bin/Doctrine
Then I created 2 folders on root 'model' and 'proxies'.
Now we need to bootstrap Doctrine.
--- Bootsrap ---
<?php
// test.php
require 'DoctrineORM/Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', 'DoctrineORM');
$classLoader->register(); // register on SPL autoload stack
$classloader = new \Doctrine\Common\ClassLoader('model', __DIR__);
$classloader->register();
$config = new \Doctrine\ORM\Configuration();
$cache = new \Doctrine\Common\Cache\ArrayCache();
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
$driverImpl = $config->newDefaultAnnotationDriver('model');
$config->setMetadataDriverImpl($driverImpl);
$config->setProxyDir('proxies');
$config->setProxyNamespace('proxies');
$config->setAutoGenerateProxyClasses(true);
$config->getAutoGenerateProxyClasses();
$connectionOptions = array(
'driver' => 'pdo_mysql',
'dbname' => 'test',
'user' => '[DB_User]',
'password' => '[DB_Pass]'
);
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
//echo 'Hello World!' . PHP_EOL;
// Get result from Table
$q = $em->createQuery('SELECT c FROM model\User c ORDER BY c.name');
$t = $q->getResult();
echo "<pre>"; print_r($t);
// Save a new User to DB
$uu = new model\User();
$uu->name = 'test name1';
$uu->age = 4;
$em->persist($uu);
$em->flush();
--- Bootsrap ---
Then I created a model file in model directory
--- Model - User.php ---
<?php
// Model File model/User.php
namespace Model;
/** #Entity #Table(name="users") */
class User
{
/**
* #Id #Column(type="integer")
* #GeneratedValue(strategy="AUTO")
*/
public $id;
/** #Column(type="string", length=50) */
public $name;
/** #Column(type="integer", length=50) */
public $age;
}
--- Model - User.php ---
My complete folder structure now looks like below.
./test
DoctrineORM/
DoctrineORM/bin
DoctrineORM/bin/Doctrine
Model/
Model/User.php
test.php
Hope this will help you. If you need any further help I can send you the complete source which works fine at my machine.
You don't need the entire Symfony framework. Just the bits that Doctrine relies on.
If you download the current version of the ORM component (right now at BETA2), it will include a folder called Symfony (probably in lib/vendor/Symfony, but it tends to move around with new releases). You need to make sure that the ClassLoader in doctrine.php or cli-config.php can find that Symfony folder.
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', __DIR__ . '/path/to/Symfony');
$classLoader->register();
I hope this information is accurate. The Doctrine team keeps messing with the structure of the release they closer they get to a final version.
If you want to use the command line interface in the new Doctrine 2 beta you also have to install the Symfony 2 framework (because it includes the Console Helper) and put it into your include path.
As far as I know there is currently no PEAR installation available, so you will have to download the sources from the Symfony 2 website or via Git.
On a sidenote: It seems that you also tried to execute doctrine.php at a path where it doesn’t exist. That’s the reason why you got the
Could not open input file: doctrine.php
error message.
Doctrine v2.* is stored in bin dir.
Try like this :
$ vendor/bin/doctrine orm:conver-mapping xml src/ --from-database --force
Dont put PHP on start.