I have two laravel api projects,
1-used for mysql database and another used for mssql database
I called mysql project api service to get orders and some data related with order are exists in mssql and I have written a call of curl in 1st project to get from another information related with order from mssql project api (mssql service api url = localhost/laravelmssql/api/getorderInfo/OrderID)
mssql service call working fine from browser
but when I call it from 1st project with curl its getting wrong database which is configured in 1st project
Note:
This is adding correct database connection info in $_SERVER when I call it from browser
[DB_PORT] => 1433
[DB_DATABASE] => MSSQL DATABASE
[DB_USERNAME] => MSSQL_USERNAME
[DB_PASSWORD] => MSSQL_PASSWORD
but when I call it from curl the $_SERVER don't have these above variables
I have updated code
2nd-project controller for
class OrderController extends BaseController{
public function getOrderDetail(){
// echo env('DB_DATABASE').'-'.str_random(10); // ITS GETTING 1ST CONFIGURE DATABASE NAME
// echo '<pre>';print_r($_SERVER);echo '</pre>'; die;
//
// echo '<pre>';print_r($_SERVER);echo '</pre>';
return OrderDetailsModel::getOrderDetail(1);
}
}
1st-Project Call
//NOT WORKING
$curl_handle=curl_init();
curl_setopt($curl_handle, CURLOPT_URL,'http://apiproject/api/getOrderDetail/1');
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
$query = curl_exec($curl_handle);
curl_close($curl_handle);
echo $query;
//NOT WORKING
dd(file_get_contents('http://apiproject/api/getOrderDetail/1'));
//NOT WORKING
$response = Curl::to(env('MSSQLAPILINK').'get/getOrderDetail/'.$orderID)->withHeaders([
'DB_DATABASE:0000',
'DB_USERNAME:0000',
'DB_PASSWORD:0000',
'DB_PREFIX:000',
])->get();
dd($response);
Related
I have created a service provider which provides a class App\Path. This is loaded up through Eloquent using $request->getPathInfo()
$this->app->singleton(Path::class, function($app)
{
$request = $app->make(\Illuminate\Http\Request::class);
$path = Path::with(['template', 'parts'])->findOrFail($request->getPathInfo());
return $path;
});
The app works fine and as expected. However when I want to use Artisan I get the following error:
In Builder.php line 369:
No query results for model [App\Path] /
This prevents me from clearing caches, creating models etc. It seems that Laravel runs register() when running any artisan command and when this done, the request path is "/" which doesn't exist in the DB. Is there a better way to populate the Path object? The only way to solve this seems to add a dummy record for "/".
You can check whether the app is running from console and adjust its logic, for example:
$this->app->singleton(Path::class, function($app)
{
if ($app->runningInConsole()) {
return null;
}
$request = $app->make(\Illuminate\Http\Request::class);
$path = Path::with(['template', 'parts'])->findOrFail($request->getPathInfo());
return $path;
});
I have two projects in laravel, one only with my vision (AppView) and another with the web service (AppWs), in my web service I have the following route
Route project AppWs
Route::group(['prefix' => 'api'],function(){
Route::group(['prefix' => 'user'], function(){
Route::group(['prefix' => 'tipoprojeto'], function(){
Route::get('','Painel\TipoProjetoController#All');
});
});
});
when I access http://localhost/WebServiceApp/public/api/user/tipoprojeto/
it returns me an array with all the data, until then all right.
in my other project, I have a TypeProjectController controller and I have my index () method (AppView), so how can I retrieve the webservice data to load here?
EDIT
AppWs responsible for manipulating the data
public function All(){
return $this->ModelTipoProjeto->paginate(5);
}
AppView responsible for displaying data
Route::resource('/Painel/TipoProjeto', 'Painel\TipoProjetoController');
public function index()
{
$getData = `http://localhost/WebServiceApp/public/api/user/tipoprojeto/` // <~~
return view('Painel.TipoProjeto.index');
}
Retrieve the data that the AppWebservice link returns
First of all in order to consume an external service you have to perfrom a http request towards the endpoint where you intend to get the data form.
Your endpoing: http://localhost/WebServiceApp/public/api/user/tipoprojeto/
Install guzzle which is a php curl wrapper to perform http calls.
In your root dir open command line and inject guzzle in your project by firing :
composer require guzzlehttp/guzzle
Make sure you import guzzle at the top of the controller by adding
use GuzzleHttp\Client;
Then go to your index method and do the following:
public function index(){
// Create a client with a base URI
$client = new GuzzleHttp\Client(['base_uri' => 'http://localhost/WebServiceApp/public/api/user/tipoprojeto/']);
// Send a request to http://localhost/WebServiceApp/public/api/user/tipoprojeto/
$response = $client->request('GET', 'test');
// $response contains the data you are trying to get, you can do whatever u want with that data now. However to get the content add the line
$contents = $response->getBody()->getContents();
dd($contents);
}
$contents contains the data now you can do whatever you want.
I am learning Laravel 5.4, Still new to Laravel and PHPUnit. Everything is working great after following online basic tutorial.
This test function is working correctly when run phpunit
public function testBasicExample()
{
$response = $this->call( 'GET' , '/welcome');
$this->assertTrue(strpos($response->getContent(), 'Laravel') !== false);
}
Problem comes when I try to test Api
Steps I took
Create Api route for books
Return all users from users talbe as json from localhost/api/books/
public function index()
{
$users = DB::table('users')->get()->toJson();
echo $users;
}
I open the link in browser and json is returned correctly
copy and pasted json into online json validator jsonlint and it is valid.
Create a new test function
public function test_index_method_returns_all_books()
{
$response = $this->call( 'GET' , '/api/books/');
$this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getContent(),true);
$this->assertJson($data);
}
run phpunit
200 status test passed but assertJson did not pass.
I tried to do var_dump for $response->getContent() and found out it return empty.
now I am not able to get getContent() for api/book/. Does anyone know if there is a solution for this?
Thanks.
Here is a screenshot
Try create some data with a factory before you call the api:
e.g.:
factory(\App\Books::class, 20)->create();
then
$response = $this->call( 'GET' , '/api/books/');
If you had set ":memory:" as your database on phpunit.xml, you will no longer see any data from your local database, that's why you should use factory instead.
Is there a way, in Laravel 5, to call routes internally/programmatically from within the application? I've found a lot of tutorials for Laravel 4, but I cannot find the information for version 5.
Using laravel 5.5, this method worked for me:
$req = Request::create('/my/url', 'POST', $params);
$res = app()->handle($req);
$responseBody = $res->getContent();
// or if you want the response to be json format
// $responseBody = json_decode($res->getContent(), true);
Source:
https://laracasts.com/discuss/channels/laravel/route-dispatch
*note: maybe you will have issue if the route you're trying to access
has authentication middleware and you're not providing the right credentials.
to avoid this, be sure to set the correct headers required so that the request is processed normally (eg Authorisation bearer ...).
UPDATE: i've tried this method with laravel 8 and it works but if you're using PHP version 8.0 you might need to call opcache_reset(); before this line $req = Request::create('/my/url', 'POST', $params); to avoid an error.
see guzzlehttp/guzzle dosn't work after update php to php 8 for more info
You may try something like this:
// GET Request
$request = Request::create('/some/url/1', 'GET');
$response = Route::dispatch($request);
// POST Request
$request = Request::create('/some/url/1', 'POST', Request::all());
$response = Route::dispatch($request);
You can actually call the controller that associates to that route instead of 'calling' the route internally.
For example:
Routes.php
Route::get('/getUser', 'UserController#getUser');
UserController.php
class UserController extends Controller {
public function getUser($id){
return \App\User::find($id);
};
}
Instead of calling /getUser route, you can actually call UserController#getUser instead.
$ctrl = new \App\Http\Controllers\UserController();
$ctrl->getUser(1);
This is the same as calling the route internally if that what you mean. Hope that helps
// this code based on laravel 5.8
// I tried to solve this using guzzle first . but i found guzzle cant help me while I
//am using same port. so below is the answer
// you may pass your params and other authentication related data while calling the
//end point
public function profile(){
// '/api/user/1' is my api end please put your one
//
$req = Request::create('/api/user/1', 'GET',[ // you may pass this without this array
'HTTP_Accept' => 'application/json',
'Content-type' => 'application/json'
]);
$res = app()->handle($req);
$responseBody = json_decode($res->getContent()); // convert to json object using
json_decode and used getcontent() for getting content from response
return response()->json(['msg' =>$responseBody ], 200); // return json data with
//status code 200
}
None of these answers worked for me: they would either not accept query parameters, or could not use the existing app() instance (needed for config & .env vars).
I want to call routes internally because I'm writing console commands to interface with my app's API.
Here's what I did that works well for me:
<?php // We're using Laravel 5.3 here.
namespace App\Console;
use App\MyModel;
use App\MyOtherModel;
use App\Http\Controllers\MyController;
use Illuminate\Console\Command;
class MyCommand extends Command
{
protected $signature = 'mycommand
{variable1} : First variable
{variable2} : Another variable';
public function handle()
{
// Set any required headers. I'm spoofing an AJAX request:
request()->headers->set('X-Requested-With', 'XMLHttpRequest');
// Set your query data for the route:
request()->merge([
'variable1' => $this->argument('variable1'),
'variable2' => $this->argument('variable2'),
]);
// Instantiate your controller and its dependencies:
$response = (new MyController)->put(new MyModel, new MyOtherModel);
// Do whatever you want with the response:
var_dump($response->getStatusCode()); // 200, 404, etc.
var_dump($response->getContent()); // Entire response body
// See what other fun stuff you can do!:
var_dump(get_class_methods($response));
}
}
Your Controller/Route will work exactly as if you had called it using curl. Have fun!
I am using codeigniter with sqlite and I have created a new library for connecting the sqlite database. The sqlite database will connect only if the session is set.
LIBRARY (userdb)
$CI =& get_instance();
if( $CI->session->userdata('user') ){
$userId = $CI->session->userdata('user');
$this->conDb = new PDO("sqlite:" . BASEPATH . "sqlitedb/" . $userId . "/data.db");
}else{
$userId = '';
}
And I execute queries by using $query = $this->userdb->query($sql);
It works fine but the problem is that query only works if the page is refreshed after session is created otherwise it returns Call to a member function query() on a non-object error.
CONTROLLER
$sessiondata = array('user' => $userid);
$this->session->set_userdata($sessiondata);
$insert = $this->user_model->insert($data);
All this seems legit, if you set your userdata while the page/controller is loading it means that the librairies and other assets have been loaded already. So when your userdb library is loaded there is no sessions set yet.
You have two ways to fix this : Try to Load your library after loading your controller but for a db library this would be better to be in your config file so that it is auto loaded.
The other way would be to reload or redirect your current PAGE after the session isset. So that you can use your db library
Hope that helps You
NwK