PHP Slim Framework : Slim Application Error when using PDO - pdo

I want to use PDO with my Slim php application. When I use a simple select query and send json data to Twig page. But I keep getting this error : Slim Application Error
This is my code :
<?php
require __DIR__ . '/vendor/autoload.php';
$app = new Slim\App;
$container = $app->getContainer();
$container['view'] = function ($container) {
$templates = __DIR__ . '/templates/';
$cache = __DIR__ . '/tmp/views/';
$view = new Slim\Views\Twig($templates, array('cache' => false));
return $view;
};
$container['db'] = function ($container) {
$pdo = new PDO("mysql:host=localhost;DBName=dbsat", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
return $pdo;
};
$app->get('/', function ($request, $response) {
$sth = $this->db->prepare("SELECT * from client where id=:id");
$sth->bindParam("id", 1);
$sth->execute();
$todos = json_encode($sth->fetchAll());
$data = ['user' => $todos];
return $this->view->render($response, 'home.twig', $data);
});
$app->get('/login', function ($request, $response) {
return $this->view->render($response, 'login.twig');
});
$app->run();
?>
The problem appears at this line :
$sth = $this->db->prepare("SELECT * from client where id=:id");

Problem solved. It was caused by binding param
Message: Cannot pass parameter 2 by reference
By knowing the error I have fixed it. Thank you all.

Related

Symfony 5 - A problem with package HTTP-Client (NativeHttpClient)

I have an error that I don't understand.
I'm trying to validate the creation of a MangoPay account and I'm using the Http-Client package for the APIs (I've also installed mangopay's package).
When I try to create one, this error shows up:
Unsupported option "0" passed to "Symfony\Component\HttpClient\NativeHttpClient", did you mean "auth_basic", "auth_bearer", "query", "headers", "body", "json", "user_data", "max_redirects", "http_version", "base_uri", "buffer", "on_progress", "resolve", "proxy", "no_proxy", "timeout", "max_duration", "bindto", "verify_peer", "verify_host", "cafile", "capath", "local_cert", "local_pk", "passphrase", "ciphers", "peer_fingerprint", "capture_peer_cert_chain", "extra"?
That's the file I'm working on:
<?php
namespace App\Service;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use MangoPay;
use App\Service\MockStorage;
class CallApiService
{
private $mangoPayApi;
private $client;
public function __construct(HttpClientInterface $httpClient)
{
$this->client = $httpClient;
$this->mangoPayApi = new MangoPay\MangoPayApi();
$this->mangoPayApi->Config->ClientId = $_ENV['CLIENT_ID'];
$this->mangoPayApi->Config->ClientPassword = $_ENV['API_KEY'];
// $this->mangoPayApi->Config->TemporaryFolder = 'mangotemp';
$this->mangoPayApi->OAuthTokenManager->RegisterCustomStorageStrategy(new MockStorage());
}
public function createProfilMango($form)
{
$date = date_format($form['birthday']->getData(), "Ymd");
$userMango = $this->client->request(
'POST',
$_ENV['SERVER_URL'] . '/' . $_ENV['VERSION'] . '/' . $_ENV['CLIENT_ID'] .'/users/natural',
[
$UserNatural = new MangoPay\UserNatural(),
$UserNatural->FirstName = $form['firstname']->getData(),
$UserNatural->LastName = $form['lastname']->getData(),
$UserNatural->Email = $form['email']->getData(),
$UserNatural->Address = new MangoPay\Address(),
$UserNatural->Address->AddressLine1 = $form['streetNumber']->getData() . " " . $form['address']->getData(),
$UserNatural->Address->AddressLine2 = "",
$UserNatural->Address->City = $form['city']->getData(),
$UserNatural->Address->Region = "",
$UserNatural->Address->PostalCode = $form['zipCode']->getData(),
$UserNatural->Address->Country = "FR",
$UserNatural->Birthday = intval($date),
$UserNatural->Nationality = $form['nationality']->getData(),
$UserNatural->CountryOfResidence = "FR",
$UserNatural->Capacity = "NORMAL",
$Result = $this->mangoPayApi->Users->Create($UserNatural),
]
);
return $userMango;
}
}
The CallApiService.php is called upon the signup controller of my website:
// RegistrationController.php
[...]
public function register(CallApiService $callApiService, User $user = null, Request $request, UserPasswordHasherInterface $userPasswordHasher, UserAuthenticatorInterface $userAuthenticator, AppCustomAuthenticator $authenticator, EntityManagerInterface $entityManager): Response
{
if(!$user){
$user = new User();
}
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// encode the plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
);
$callApiService->createProfilMango($form);
// $entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
// do anything else you need here, like send an email
// return $userAuthenticator->authenticateUser(
// $user,
// $authenticator,
// $request,
// // 'main' // firewall name in security.yaml
// );
}
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
'editMode'=> $user-> getId() !== null,
]);
}
I've tried to change the $client value with new NativeHttpClient() and new CurlHttpClient() but the error doesn't change.
What's the error? How can I fix it?

How to set up multiple PDO database connections in slim 4 and access them in a repository?

I tried to set up SLIM 4 with 2 PDO database connections.
I can't access the db nor db2 from a repository.
I guess I'm doing something wrong
I followed the slim 4 skeleton.
I created a db.php file in app for adding the db's definition in the container
I included db.php in index.php
I tried to access the db or db2 from a repository but it is not working
Here are my files :
app/db.php
declare(strict_types=1);
use PDO;
use DI\ContainerBuilder;
return function (ContainerBuilder $containerBuilder) {
// Global Settings Object
$containerBuilder->addDefinitions([
'db' => function (ContainerInterface $c) {
$settings = $c->get('settings');
$dbSettings = $settings['db'];
return new PDO('mysql:host=' . $dbSettings['host'] . ';dbname=' . $dbSettings['db'], $dbSettings['username'], $dbSettings['password'], $dbSettings['options']);
},
'db2' => function (ContainerInterface $c) {
$settings = $c->get('settings');
$dbSettings = $settings['db2'];
return new PDO('mysql:host=' . $dbSettings['host'] . ';dbname=' . $dbSettings['db'], $dbSettings['username'], $dbSettings['password'], $dbSettings['options']);
}
]);
};
public/index.php
declare(strict_types=1);
use App\Application\Handlers\HttpErrorHandler;
use App\Application\Handlers\ShutdownHandler;
use App\Application\ResponseEmitter\ResponseEmitter;
use DI\ContainerBuilder;
use Slim\Factory\AppFactory;
use Slim\Factory\ServerRequestCreatorFactory;
require __DIR__ . '/../vendor/autoload.php';
// Instantiate PHP-DI ContainerBuilder
$containerBuilder = new ContainerBuilder();
if (false) { // Should be set to true in production
$containerBuilder->enableCompilation(__DIR__ . '/../var/cache');
}
// Set up settings
$settings = require __DIR__ . '/../app/settings.php';
$settings($containerBuilder);
// Set up dependencies
$dependencies = require __DIR__ . '/../app/dependencies.php';
$dependencies($containerBuilder);
// Set up db, added by PF
$db = require __DIR__ . '/../app/db.php';
$db($containerBuilder);
// Set up repositories
$repositories = require __DIR__ . '/../app/repositories.php';
$repositories($containerBuilder);
// Build PHP-DI Container instance
$container = $containerBuilder->build();
// Instantiate the app
AppFactory::setContainer($container);
$app = AppFactory::create();
$callableResolver = $app->getCallableResolver();
// Register middleware
$middleware = require __DIR__ . '/../app/middleware.php';
$middleware($app);
// Register routes
$routes = require __DIR__ . '/../app/routes.php';
$routes($app);
/** #var bool $displayErrorDetails */
$displayErrorDetails = $container->get('settings')['displayErrorDetails'];
// Create Request object from globals
$serverRequestCreator = ServerRequestCreatorFactory::create();
$request = $serverRequestCreator->createServerRequestFromGlobals();
// Create Error Handler
$responseFactory = $app->getResponseFactory();
$errorHandler = new HttpErrorHandler($callableResolver, $responseFactory);
// Create Shutdown Handler
$shutdownHandler = new ShutdownHandler($request, $errorHandler, $displayErrorDetails);
register_shutdown_function($shutdownHandler);
// Add Routing Middleware
$app->addRoutingMiddleware();
// Add Error Middleware
$errorMiddleware = $app->addErrorMiddleware($displayErrorDetails, false, false);
$errorMiddleware->setDefaultErrorHandler($errorHandler);
// Run App & Emit Response
$response = $app->handle($request);
$responseEmitter = new ResponseEmitter();
$responseEmitter->emit($response);
src/Domain/ObContact/ObContactRepository.php
declare(strict_types=1);
namespace App\Domain\ObContact;
use PDO;
class ObContactRepository
{
/**
* #var PDO The database db
*/
private $db;
private $db2;
/**
* Constructor.
*
* #param PDO $db The database db
*/
public function __construct(PDO $db, PDO $db2)
{
$this->db = $db;
$this->db2 = $db2;
}
public function findByEmail(string $email)
{
if (empty($email))
return false;
return $this->db
->query('SELECT * FROM ob_contact WHERE email=:email')
->execute([':email' => $email])
->fetch();
}
}
Did you install PDO?
$ composer require faapz/pdo
Source:
https://github.com/FaaPz/PDO

Laravel 5.8 rest client how to save api token in the .env

I should like to insert the return token from api into the .env in when after i want pass it header in
<!-- language: php -->
class GuzzleController extends Controller
{
public function getToken()
{
$client = new Client();
$request = $client->request('POST', 'http://192.168.53.27:1996/api/login/',
[
'form_params' => [
'user_name' => 'userName',
'password' => 'Passs',
]
]);
return json_decode((string)$request->getBody(), true);
}
}
As same question has been answere here;
This method should save new value to your .env file
private function setEnvironmentValue($envKey, $envValue)
{
$envFile = app()->environmentFilePath();
$str = file_get_contents($envFile);
$str .= "\n"; // In case the searched variable is in the last line without \n
$keyPosition = strpos($str, "{$envKey}=");
$endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
$str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
$str = substr($str, 0, -1);
$fp = fopen($envFile, 'w');
fwrite($fp, $str);
fclose($fp);
}
usage
$this->setEnvironmentValue('DEPLOY_SERVER', 'forge#122.11.244.10');

My file not in uploads directory after upload was successful

I try to upload file using Yii2 file upload and the file path was successful saved to the database but the file was not saved to the directory I specify.. below is my code..
<?php
namespace backend\models;
use yii\base\Model;
use yii\web\UploadedFile;
use yii\Validators\FileValidator;
use Yii;
class UploadForm extends Model
{
/**
* #var UploadedFile
*/
public $image;
public $randomCharacter;
public function rules(){
return[
[['image'], 'file', 'skipOnEmpty' => false, 'extensions'=> 'png, jpg,jpeg'],
];
}
public function upload(){
$path = \Yii::getAlias("#backend/web/uploads/");
$randomString = "";
$length = 10;
$character = "QWERTYUIOPLKJHGFDSAZXCVBNMlkjhgfdsaqwertpoiuyzxcvbnm1098723456";
$randomString = substr(str_shuffle($character),0,$length);
$this->randomCharacter = $randomString;
if ($this->validate()){
$this->image->saveAs($path .$this->randomCharacter .'.'.$this->image->extension);
//$this->image->saveAs(\Yii::getAlias("#backend/web/uploads/{$randomString}.{$this->image->extension}"));
return true;
}else{
return false;
}
}
}
The controller to create the fileupload
namespace backend\controllers;
use Yii;
use backend\models\Product;
use backend\models\ProductSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use backend\models\UploadForm;
use yii\web\UploadedFile;
public function actionCreate()
{
$addd_at = time();
$model = new Product();
$upload = new UploadForm();
if($model->load(Yii::$app->request->post())){
//get instance of the uploaded file
$model->image = UploadedFile::getInstance($model, 'image');
$upload->upload();
$model->added_at = $addd_at;
$model->image = 'uploads/' .$upload->randomCharacter .'.'.$model->image->extension;
$model->save();
return $this->redirect(['view', 'product_id' => $model->product_id]);
} else{
return $this->render('create', [
'model' => $model,
]);
}
}
Does it throw any errors?
This is propably permission issue. Try changing the "uploads" directory permission to 777 (for test only).
You load your Product ($model) with form data.
if($model->load(Yii::$app->request->post()))
But Uploadform ($upload) never gets filled in your script. Consequently, $upload->image will be empty.
Since you declare 'skipOnEmpty' => false in the file validator of the UploadForm rules, the validation on $upload will fail.
That is why your if statement in the comments above (if($upload->upload()) doesn't save $model data.
I don't see why you would need another model to serve this purpose. It only complicates things, so I assume its because you copied it from a tutorial. To fix and make things more simple, just do the following things:
Add property to Product model
public $image;
Add image rule to Product model
[['image'], 'file', 'skipOnEmpty' => false, 'extensions'=> 'png, jpg,jpeg'],
Adjust controller create action
public function actionCreate()
{
$model = new Product();
if($model->load(Yii::$app->request->post()) && $model->validate()) {
// load image
$image = UploadedFile::getInstance($model, 'image');
// generate random filename
$rand = Yii::$app->security->generateRandomString(10);
// define upload path
$path = 'uploads/' . $rand . '.' . $image->extension;
// store image to server
$image->saveAs('#webroot/' . $path);
$model->added_at = time();
$model->image = $path;
if($model->save()) {
return $this->redirect(['view', 'product_id' => $model->product_id]);
}
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
Something like this should do the trick.
Your UploadForm class is already on Backend so on function upload of UploadForm Class it should be like this:
Change this line:
$path = \Yii::getAlias("#backend/web/uploads/");
to this:
$path = \Yii::getAlias("uploads")."/";

Is there a way to get the last error in php4

PHP 5 has error_get_last. Is there any way to completely or at least partially replicate the same functionality in PHP4.3?
Ripped from the PHP manual (courtesy of php at joert dot net):
<?php
if( !function_exists('error_get_last') ) {
set_error_handler(
create_function(
'$errno,$errstr,$errfile,$errline,$errcontext',
'
global $__error_get_last_retval__;
$__error_get_last_retval__ = array(
\'type\' => $errno,
\'message\' => $errstr,
\'file\' => $errfile,
\'line\' => $errline
);
return false;
'
)
);
function error_get_last() {
global $__error_get_last_retval__;
if( !isset($__error_get_last_retval__) ) {
return null;
}
return $__error_get_last_retval__;
}
}
?>
Yes it is, but you will have to do some programming, you need to attach error handler
$er_handler = set_error_handler("myErrorHandler");
but before this you need to write your "myErrorHandler"
function myErrorHandler($errNumber, $errString, $errFile, $errLine)
{
/*now add it to session so you can access it from anywhere, or if you have class with the static variable you can save it there */
$_SESSION["Error.LastError"] = $errNumber . '<br>' . $errString . '<br>' . $errFile . '<br>' . $errLine;
}
Now when error is occured you can get it by
if(isset($_SESSION["Error.LastError"]))
$str = $_SESSION["Error.LastError"];
now to replicate your method you need to create function
function get_last_error()
{
$str = "";
if(isset($_SESSION["Error.LastError"]))
$str = $_SESSION["Error.LastError"];
return $str;
}