PDO Adaptive Server connection failed when connecting to MSSQL server in FuelPHP - php

FuelPHP seems to be doing something odd when I try to connect to a MSSQL database via PDO.
Working Outside of FuelPHP
I have tried the following in a vanilla PHP page on my local server:
<?php
$mssql = new \PDO('dblib:host=<IP OF HOST>;dbname=<DBNAME>', '<USER>', '<PASS>');
And everything works fine. It connects and I can easily query the DB like I would expect.
NOT Working Inside of FuelPHP
However, when I try adding the connection in config/db.php with basically the same information an exception is thrown.
<?php
return array(
'mssql' => array(
'connection' => array(
'dsn' => 'dblib:host=<IP OF HOST>;dbname=<DBNAME>',
'username' => '<USER>',
'password' => '<PASS>',
),
'type' => 'pdo',
'table_prefix' => '',
),
);
And subsequently try to query the DB within FuelPHP like so:
$q = \DB::select()
->from('table')
->limit(5);
$r = $q->execute('mssql');
The following exception is thrown: Fuel\Core\Database_Exception [ 20002 ]: SQLSTATE[01002] Adaptive Server connection failed (severity 9)
What the kicker is when I try to just do my original basic connection inside of a controller of FuelPHP I get the same error message. So it appears FuelPHP is playing havoc with even a normal PDO connection.
Example of basic connection attempt within a FuelPHP controller.
<?php
class Controller_Welcome extends Controller
{
public function action_index()
{
$mssql = new \PDO('dblib:host=<IP OF HOST>;dbname=<DBNAME>', '<USER>', '<PASS>');
}
}
For reference I am using PHP 5.3.16 and using FreeTDS to connect from my OS X laptop. (This shouldn't be an issue though since the vanilla version works.)

Related

Can't connect custom script to cosmos db using brightzone gremlin-php

I'm trying to build an app around the brightzone gremlin php api for cosmos db (free tier). I can get the api to work through the console (with the provided app) but when I try to use my own custom functions to call the exact same methods available in the API class – practically copying the code, which worked through the console) – I get this...
Fatal error: Uncaught TypeError: fwrite(): Argument #1 ($stream) must be of type resource, null given {...}
on line 174 in vendor/brightzone/gremlin-php/src/Connection.php
I'm new to Gremlin in general, and have limited experience using APIs.
Is this some limitation to the free tier, or have I completely misunderstood something?
edit
I decided to test the api with varying degrees of extra setup on my part...
Running the PHP CLI script: connect.php (included in cosmos graph php getting started quickstart) from a browser through xampp gave no errors. I'm seeing a spike in requests in cosmos' dashboard when I do this, so I know it's hitting the database.
The same test through a vhost alias also gave no errors, while hitting the database.
Creating my own function that calls the class and methods results in the fwrite error above.
Initializing the object
This is the same on both the CLI version and my script.
<?php
require_once('define.php');
require_once('vendor/autoload.php');
use \Brightzone\GremlinDriver\Connection;
$db = new Connection([
'host' => HOST,
'username' => USER,
'password' => PASS
,'port' => PORT
// Required parameter
,'ssl' => TRUE
]);
code comparison
Here's the provided CLI script I'm trying to emulate...
function countVertices($db)
{
$query = "g.V().count()";
printf("\t%s\n\tQuery: %s\n", "Counting all the vertices.", $query);
$result = $db->send($query);
if($result)
{
printf("\tNumber of vertices in this graph: %s\n\n", $result[0]);
}
}
This results in an instant readout of the printf commands meant for command line responses, with correct data from the result property of the object, showing it was initialized, and then functioned properly.
but
Here's how I'm trying to call the method...
$query = "g.V().count()";
$result = $db->send($query);
var_dump($result);
The object initializes fine, but calling the send method throws the fwrite error.
Seriously... what am I missing?
I failed to check the END of the CLI php script, which had a "try" catch statement running all the functions. If I had checked, I'd have seen that the open and close methods...
$db->open();
//<--whatever querying here-->
$db->close();
are necessary to get the gremlin driver connected.
It's all working now with:
<?php
require_once('define.php'); //custom script defining credentials as constants
require_once('vendor/autoload.php');
use \Brightzone\GremlinDriver\Connection;
error_reporting(E_ALL ^ E_WARNING);
$db = new Connection([
'host' => HOST,
'username' => USER,
'password' => PASS,
'port' => '443'
// Required parameter
,'ssl' => TRUE
]);
$db->timeout = 0.5;
$db->open();
$query = "g.V().count()";
var_dump($db->send($query));
$db->close();
?>
This prints the correct response.

Codeigniter 3 - How to use Forge Class to create a database schema?

I'm using CodeIgniter 3.1.0 to develop an app. In order to improve installation, I've written an Install_Controller, and an Install_Model.
I want to use Database Forge class to manage the database schema, but it's not very clear in user guide and nothing on Google helps.
I need to use $this->dbforge->create_database, because the user knows nothing about database, so all he will do is MySQL "Next, next, install" and then run a batch file that run PHP as web server, so from Chrome he can use URL to install the app.
User guide says: In order to initialize the Forge class, your database driver must already be running, since the forge class relies on it.
So I have setup the config/database.php with user, pwd, dbname and so on... Even because I need it to use in app.
When I try to load the URL to install the app, give me the error: Message: mysqli::real_connect(): (HY000/1049): Unknown database 'test'
So, how can I use Forge Class to create database schema, if I need to have it first?
Some code...
$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'root',
'password' => 'root',
'database' => 'test',
'dbdriver' => 'mysqli'
);
$autoload['libraries'] = array('database');
class Install extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
public function index()
{
$this->load->model('install_model');
$this->install_model->createDabase();
}
}
class Install_model extends CI_Model {
function __construct() {
parent::__construct();
}
function createDabase() {
$this->load->dbforge();
if ($this->dbforge->create_database('test'))
echo 'Database created!';
else
echo 'Database error!';
}
}
After try and get a lot of opinions, the only way is as I commented:
Remove database from autoloader;
Use multiple databases, the default one is the same, but create a second one having empty database name;
Use the second database with Forge Class, instead of the default, only for create database and tables;
Change manually for the the default database and use it after that.

How to set second database in laravel when main connection is down

I have a laravel project with many connections to different IP's.
I want laravel to connect to a backup database in the case that the main SQL server was down
Example.
192.168.1.2 -> SQL DB #1
192.168.1.3 -> SQL DB #1 Backup
If 192.168.1.2 goes down, laravel must connect to 192.168.1.3
I'd like to do this in database.php file, but I think that's impossible.
I was trying to test connection before make a query like this:
if(DB::connection('connection')->getDatabaseName())
but it seems that it save data in cache and it still throw database name even if I shutdown the SQL server
For this answer, I'm considering Laravel 5.
By debugging a model query, I've found out that Laravel connections support not a single host, but a list of them.
[
'driver' => 'sqlsrv',
'host' => [
'192.168.1.2',
'192.168.1.3',
],
'database' => 'database_name',
'username' => 'username',
'password' => 'password',
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'transaction_isolation' => PDO::SQLSRV_TXN_READ_UNCOMMITTED, // Not required, but worth mentioning it's possible to define it here too
'options' => [],
]
The underlying method behind Laravel connections resolving is Illuminate\Database\Connectors::createPdoResolverWithHosts which has the following behavior:
protected function createPdoResolverWithHosts(array $config)
{
return function () use ($config) {
foreach (Arr::shuffle($hosts = $this->parseHosts($config)) as $key => $host) {
$config['host'] = $host;
try {
return $this->createConnector($config)->connect($config);
} catch (PDOException $e) {
continue;
}
}
throw $e;
};
}
Such behavior means that Laravel will randomly pick one of the connection's hosts and try to connect to them. If the attempt fails, it keeps trying until no more hosts are found.
You could define two mysql connections in app/config/database.php
and using a middleware you could define the db that should be connected to.
You can find a more elaborate explanation in this URL:
http://fideloper.com/laravel-multiple-database-connections
i recently started searching for the same thing and to change the connection as soon as possible you can either
add the check inside a service provider
or through a global middleware
try{
\DB::connection()->getPdo(); // check if we have a connection
}catch{
\DB::purge(config('database.default')); // disconnect from the current
\DB::setDefaultConnection('my-fallback-db'); // connect to a new one
}
also check laravel api docs for more info.

propel sql:insert throws error 'Unable to parse contents of sqldb.map'

I'm trying to build a project with Propel these days. I did the basic 'bookstore' tutorial on propelorm.org/documentation/02-buildtime.html, but when I'm trying to finally insert the generated sql code via propel, to fill the database, the following error is thrown:
[Exception] Unable to parse contents of "/sqldb.map".
Unfortunately I've got no idea what went wrong; I followed the tutorial as precisely as possible.
Information about my installation and what I've done so far:
1) Localhost installation (Mac OS 10.8.5) with PHP 5.4.27 (DOM Module, PDO and SPL enabled) and MySQL 5.6.19.
2) successfully parsed Composer.json with:
{
"require": {
"propel/propel": "~2.0#dev"
},
"autoload": {
"classmap": ["bookstoreDb/generated-classes/"]
}
}
3) created a schema.xml with foreign keys, exactly like in the tutorial (propelorm.org/documentation/02-buildtime.html).
4) created a config file, propel.yaml, in subfolder 'conf', again like in the tutorial.
5) used the propel scripts to generate the necessary sql (propel sql:build), model (propel model:build) and configuration files (propel config:convert). The result of these commands are as indicated as in the tutorial.
6) created the database 'bookstore' successfully via terminal.
7) trying to insert the sql code via propel sql:insert. Now the error as described above is thrown:
[Exception] Unable to parse contents of "/sqldb.map".
Here is the index.php of the project:
// setup the autoloading
require_once 'vendor/autoload.php';
// setup Propel
require_once 'bookstoreDb/generated-conf/config.php';
// Here I get the parse error: parse error in ../bookstore/bookstoreDb/generated-classes/Base/Author.php on line 138
$author = new Author();
$author->setFirstName('Jane');
$author->setLastName('Austen');
$author->save();
And here the config.php:
$serviceContainer = \Propel\Runtime\Propel::getServiceContainer();
$serviceContainer->checkVersion('2.0.0-dev');
$serviceContainer->setAdapterClass('bookstore', 'mysql');
$manager = new \Propel\Runtime\Connection\ConnectionManagerSingle();
$manager->setConfiguration(array (
'classname' => 'Propel\\Runtime\\Connection\\ConnectionWrapper',
'dsn' => 'mysql:host=localhost;dbname=bookstore',
'user' => 'root',
'password' => 'password',
'attributes' =>
array (
'ATTR_EMULATE_PREPARES' => false,
),
));
$manager->setName('bookstore');
$serviceContainer->setConnectionManager('bookstore', $manager);
$serviceContainer->setDefaultDatasource('bookstore');
Where may be the problem? And is there some other way to setup a basic project? I'd appreciate every help! Thanks!
I submitted an issue for this: https://github.com/propelorm/Propel2/issues/694
SqlBuildCommand uses configured sql-dir
$manager->setWorkingDirectory($generatorConfig->getSection('paths')['sqlDir'])
SqlInsertCommand only uses the command line option
$manager->setWorkingDirectory($input->getOption('sql-dir'));
adding --sql-dir option with correct sql dir to propel sql:insert does work
fix is submitted https://github.com/propelorm/Propel2/pull/695 but not merged yet

MongoDB PHP connection not working

<?php
$m = new MongoClient('mongodb://localhost', array(
'username' => 'wa',
'password' => 'password',
'db' => 'wa'
));
I'm using that code snippet to connect and am trying to run commands in PHP to insert / find data in a MongoDB collection or database.
I installed MongoDB and added the mongo.so extension to my php.ini.
What am I doing wrong?
Can you run just the connection code from the command line. Also you should be passing in your connection options in this format:
mongodb://[username:password#]host1[:port1][,host2[:port2:],...]/db
Use this:
<?php
$m = new MongoClient('mongodb://wa:password#localhost/wa');
?>
That will throw any errors you are having on the command line and be easy to diagnose. The responses should be self explainatory. Likely causes:
You are connecting to localhost and do not have a running mongod or mongos on this machine. [ So change tha host and possibly port].
Your user credentials are incorrect
It seems likely that case 1 applies by the very fact you are supplying user credentials, as you would be unlikely to need them if developing on your own machine. It would also be very uncommon to be running MongoDB on the same server as your application in production.
For anyone that stumbles upon this, the MongoClient is depricated and does not work with the current (as of Aug 2018) MongoDB PHP Driver. (which would be installed with the mongodb.dll file, not the *.so file)
A current example of a working connection would be:
<?php
$user = "XXXX";
$pwd = 'XXXX';
$filter = [];
if (isset($_POST['needleID'])) {
$needleID = $_POST['needleID'];
$filter = ['id'=> $needleID];
}
//Manager Class
$connection = new MongoDB\Driver\Manager("mongodb://${user}:${pwd}#localhost:27017");
// Query Class
$query = new MongoDB\Driver\Query($filter);
// Output of the executeQuery will be object of MongoDB\Driver\Cursor class
$rows = $connection->executeQuery('sedwe.defaultConfig', $query);
// Convert rows to Array and sedn result back to client
$rowsArr = $rows->toArray();
echo json_encode($rowsArr);
?>

Categories