Zend DB call to undefined method where() - zend-framework

The below query returns a Call to undefined method Zend\Db\ResultSet\ResultSet::where() error.
$rowset = $this->table->select()->where("email='$str'");
This however works:
$rowset = $this->table->select(["email" => $str]);
Here are the dependencies:
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Select;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\TableGateway\Feature\RowGatewayFeature;
use Zend\Db\TableGateway\Feature\MetadataFeature;
use Zend\Db\TableGateway\Feature\FeatureSet;
Anyone knows why? I'm basically just trying to use 'where' to run an OR MySql query.

Figured it out from the obvious error message indicated that the method select would return a result set. I think I was looking at sources for a different Zend DB version. This answer is for version 2.9.
Here's how to customize the select options:
$select = new Select;
$select->from("table_name");
$select->where("email='$str' OR uid='$str'");
$rowset = $this->table->selectWith($select);
Hope this eventually helps someone.

Related

Eloquent error: A facade root has not been set

I have been using Eloquent as a standalone package in Slim Framework 2 successfully.
But now that I want to make use of Illuminate\Support\Facades\DB since I need to show some statistics by getting the info from 2 tables and using a Left Join and a Counter from the database like this:
use Illuminate\Support\Facades\DB;
$projectsbyarea = DB::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id');
I get the following error:
Type: RuntimeException
Message: A facade root has not been set.
File: ...\vendor\illuminate\support\Facades\Facade.php
Line: 206
How can I solve it?
So far I have found out, in this link that I need to create a new app container and then bind it to the Facade. But I haven't found out how to make it work.
This is how I started the rest of my Eloquent and working fine:
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule();
$capsule->addConnection([
'my' => $app->config->get('settings'),
/* more settings ...*/
]);
/*booting Eloquent*/
$capsule->bootEloquent();
How do I fix this?
Fixed
As #user5972059 said, I had to add $capsule->setAsGlobal();//This is important to make work the DB (Capsule) just above $capsule->bootEloquent();
Then, the query is executed like this:
use Illuminate\Database\Capsule\Manager as Capsule;
$projectsbyarea = Capsule::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id')
->get();
You have to change your code to:
$Capsule = new Capsule;
$Capsule->addConnection(config::get('database'));
$Capsule->setAsGlobal(); //this is important
$Capsule->bootEloquent();
And at the beginning of your class file you have to import:
use Illuminate\Database\Capsule\Manager as DB;
I have just solved this problem by uncommenting $app->withFacades(); in bootstrap/app.php
Had the same issue with laravel 8. I replaced
use PHPUnit\Framework\TestCase;
with:
use Tests\TestCase;
Try uncommenting in app.php $app->withFacades();
Do not forget to call parent::setUp(); before.
fails
public function setUp(): void {
Config::set('something', true);
}
works
public function setUp(): void {
parent::setUp();
Config::set('something', true);
}
One random problem using phpUnit tests for laravel is that the laravel facades have not been initialized when testing.
Instead of using the standard PHPUnit TestCase class
class MyTestClass extends PHPUnit\Framework\TestCase
one can use
class UserTest extends Illuminate\Foundation\Testing\TestCase
and this problem is solved.
I got this error after running:
$ php artisan config:cache
The solution for me was to delete the /bootstrap/cache/config.php file. I'm running Laravel 5.5.
The seems to arise in multiple situation, and not just about facades.
I received the following message while running tests using PHPUnit v.9.5.4, PHP v.8.0.3 and Lumen v. 8.2.2:
PHP Fatal error: Uncaught RuntimeException: A facade root has not
been set. in path_to_project/vendor/illuminate/support/Facades/Facade.php:258
And that happened although I had apparently already configured my app.php to enable facades ($app->withFacades();), still I received this error message whenever I tried to run tests using Illuminate\Support\Facades\DB. Unfortunately, none of the other answers helped me.
This error was actually been thrown due to my configs in phpunit.xml, which didn't point to my app.php file, where I actually enabled facades.
I just had to change
<phpunit (...OTHER_PARAMS_HERE) bootstrap="vendor/autoload.php">
to
<phpunit (...OTHER_PARAMS_HERE) bootstrap="bootstrap/app.php">
Hope it helps.
wrong way
public function register()
{
$this->app->bind('Activity', function($app)
{
new Activity;
});
}
right way 👍
public function register()
{
$this->app->bind('Activity', function($app)
{
return new Activity;
});
}
---------------------------------- don't forget return
Upgrade version for php, I encountered this error while calling the interface.
$ php artisan config:cache
Deleting the /bootstrap/cache/config.php file is a very effective way.
In my project, I managed to fix this issue by using Laravel Dependency Injection when instantiating the object. Previously I had it like this:
$class = new MyClass(
new Client(),
env('client_id', 'test'),
Config::get('myapp.client_secret')
);
The same error message happened when I used Laravel env() and Config().
I introduced the Client and env in the AppServiceProvider like this:
$this->app->bind(
MyClass::class,
function () {
return new MyClass(
new Client(),
env('client_id', 'test')),
Config::get('myapp.client_secret')
);
}
and then instantiated the class like this:
$class = app(MyClass::class);
See more from https://laravel.com/docs/5.8/container .
In my case, for a while a ran a PHP project in PHP version 8, and that time I used some PHP 8 features like param definition and method's multiple return type declarations supported by only PHP 8 and above. When I downgraded from PHP 8 to PHP 7.4 I faced this issue. After removing the return types and param hinting the problems are gone.
Tested on Laravel 8.78
tests/bootstrap.php
<?php
use Illuminate\Foundation\Bootstrap\RegisterFacades;
use Illuminate\Foundation\Bootstrap\LoadConfiguration;
require_once __DIR__ . '/../vendor/autoload.php';
$app = require_once __DIR__ . '/../bootstrap/app.php';
(new LoadConfiguration())->bootstrap($app);// <------- Required for next line
(new RegisterFacades())->bootstrap($app);// <------- Add this line
Here is yet another instance of this error, happened to me after upgrading Laravel 8 to 9.
I had feature tests with a #dataProvider to supply data to those tests. Some of the data supplied by the data provider methods came from an application service. It was being initialised like this:
/**
* #dataProvider myDataProvider
*/
public function testSomeStuff(...)
{
...
}
public function myDataProvider()
{
$myService = app(Service::class); // This is trouble
return [
['test1_data' => $myService::SOME_CONSTANT],
[...],
...
];
}
This worked under Laravel 8, but not in Laravel 9. All other solutions listed in this SO thread were checked and were correctly set up.
The problem is that the application is not being inititialised until after the data provider method is run. It was presumably initialised before this stage in the Laravel 8 install. So app(Service::class) was failing due to it using facades internally.
One workaround could be to force the application to initialise earlier, in the data provider function: $this->createApplication(). I would not recommend this due to potential side effects of the test parts running in the wrong order, though it does appear to work when I tried it.
Best solution is to avoid accessing any part of the application functionality in the data provider methods. In my case it was easy to replace $myService::SOME_CONSTANT with MyService::SOME_CONSTANT after making sure those constants were public.
Hopefully this will help somebody suddenly hitting this problem running feature tests after a Laravel 9 upgrade.
If you recently upgrade Laravel on Homestead & VirtualBox environment or do not find any reason that causing please be sure your Vagrant is up to date.
Referance
I had Taylor lock this thread. The past several replies have restated the solution, which is to Upgrade to Virtualbox 6.x, the thread is locked to prevent other issues that are not related from being dogpiled on here.
#melvin's answer above works correctly.
In case someone is wondering about it, the mistake people do is to choose Yes when VSCode asks them if they are making a Unit Test. Remember, Unit Tests should really be unit tests, independent of other application features (models, factories, routes; basically anything that would require the Laravel app to be fired up). In most scenarios, people really actually want to make Feature Tests and therefore should answer No to the above question. A feature test inherits from Tests\TestCase class (which takes care of firing up Laravel app before running the test) unlike unit tests that inherit from the class PHPUnit\Framework\TestCase which use just PHPUnit and are therefore much faster.
credit with thanks to #Aken Roberts's answer here.
From Laravel Documentation: Generally, most of your tests should be feature tests. These types of tests provide the most confidence that your system as a whole is functioning as intended.

Facebook PHP API getReachEstimate

I am quite a beginner and trying to learn to apply some things in Facebook PHP SDK, but there are some things poorly explained in the documentation.
My goal is to get number of users who say are interested in both "socker" and "football".
I think a function getReachEstimate($array, $array) does exactly that, my approach would be.
use FacebookAds\Object\ReachEstimate;
use FacebookAds\Object\Fields\ReachEstimateFields;
use FacebookAds\Object\AdAccount;
$account = new AdAccount($account_id);
$reachEstimate = $account->getReachEstimate($SOME_ARRAY, $SOME_ARRAY2));
I looked in the source of SDK and this function takes two arrays, but it is nowhere explained what are these arrays must look like. If anyone has any suggestions, please let me know. Thank you.
The first parameter seems irreverent to me. But I'm not sure. Will update the answer when I find. Meanwhile here's how to do it:
Suppose following are your parameters:
$params = [
'targeting_spec' => ['geo_locations' => ['countries' => ['US']]]
];
$fields = [];
Then call it in the following way:
$adAccount = new AdAccount($adAccountId);
$adAccount->getReachEstimate($fields, $params)->getData();
So, put your Targeting Spec in $params and the calls
Hope this helps!

Yii2 mongodb Query class not found

I am trying MongoDB integration with Yii2. I tried following the instructions at https://github.com/yiisoft/yii2-mongodb but I can't seem to get it to work:
public function actionSearch($sku) {
$query = new Query;
// compose the query
$query->select()
->from('products')
->where(['skus.sku' => $sku]);
$product = $query->all();
return $this->render('product', $product);
}
My use declarations are as follows:
namespace app\controllers;
use Yii;
use yii\mongodb\Query;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
use app\models\LoginForm;
The above results in:
Class 'yii\mongodb\Query' not found
Issue was reported to yii2 issue tracker and resolved there:
Application's composer.json (basic/composer.json) did not contain the "yiisoft/yii2-mongodb": "*" line in the require section. Adding it and running composer update helped resolve the issue.

SQL from EntityDataSource

Is there an easy way to see SQL statements generated by EntityDataSource?
SQL Server profiling/tracing is not an option here.
I used to use NHProf a profiler for NHibernate and it is awesome. So I can surely say that you should try the Entity Framework Profiler
I just checked and, as for NHProf, there is a free trial version.
You can cast to ObjectQuery and call ToTraceString:
ObjectSet<User> objectSet = ObjectSet;
var query = (ObjectQuery)(objectSet.Where(u => u.LastName == "Doe").Select(u => u));
string trace = query.ToTraceString();
For tracing/caching you can try the EF Caching and Tracing Provider Wrapper. I haven't had a chance to try it yet, but it's definitely on my to do list.

correct usage of Zend_Db

I'm currently using the Zend_Db class to manage my database connections.
I had a few questions about it.
Does it manage opening connections smartly? (eg, I have a connection already open, does it know to take use of it - or do I have to constantly check if theres' already an open connection before I open a new one?)
I use the following code to fetch results (fetching in FETCH_OBJ mode):
$final = $result->fetchAll();
return $final[0]->first_name;
for some reason, fetchRow doesn't work - so I constantly use fetchAll, even when I'll only have one result (like searching WHERE id= number and id is a PK)
My question is - how much more time/memory am I sacrificing when I use fetchAll and not fetchRow, even when there's only result?
I've created the following class to manage my connections:
require 'Zend/Db.php';
class dbconnect extends Zend_Db
{
function init ()
{
$params = array (......
return Zend_Db::factory ( 'PDO_MYSQL', $params );
}
}
and then I call
$handle = dbconnect::init
$handle->select()....
is this the best way? does anyone have a better idea?
Thanks!
p.s. I'm sorry the code formatting came out sloppy here..
Lots of questions!
Does it manage opening connections
smartly?
Yes, when you run your first query, a connection is created, and subsequent queries use the same connection. This is true if you're reusing the same Zend_Db adapter. I usually make it available to my entire application using Zend_Registry:
$db = Zend_Db::factory(...) // create Db instance
Zend_Registry::set('db', $db);
//in another class or file somewhere
$db = Zend_Registry::get('db');
$db->query(...)//run a query
The above code usually goes in your application bootstrap. I wouldn't bother to extend the Zend_Db class just to initialise and instance of it.
Regarding fetchRow - I believe the key difference is that the query run is limited to 1 row, and the object returned is a Zend_Db_Table_Row rather than a Zend_Db_Table_Rowset (like an array of rows), and does not perform significantly slower.
fetchRow should be fine so post some code that's not working as there's probably a mistake somewhere.
addition to dcaunt's answer:
FetchAll returns array OR Zend_Db_Talbe_Rowset - depending on if you execute $zendDbTableModel->fetchAll() or $dbAdapter->fetchAll()
Same goes for fetchRow(). If you fail to make fetchRow working for models, it's easier to use $model->getAdapter()->fetchRow($sqlString);