MSSQL incorrect charset in php arrays - php

Need to create connect to mssql from ubuntu with php(laravel). I'm using freetds and sybase mssql adapter for it. Successfully connected to base and can select data from it. But, when i'm trying to get an array of data from table, characters have invalid charset. With one field all is ok.
Here is my freetds.conf
[global]
tds version = 8.0
client charset = UTF-8
text size = 20971520
And laravel database config
'sqlsrv' => array(
'driver' => 'sqlsrv',
'host' => 'some-ip\DB',
'database' => 'DBTEST',
'username' => 'web-testUser',
'password' => 'hereIsMyPassword',
'charset' => 'utf8',
'prefix' => '',
),
And simple function to get an array of data
Route::get('/', function()
{
return var_dump(User::all()); //if i'll try to simple return data without using var_dump it'll crash
});

Related

sqlsrv_connect works fine in php but fails in laravel on the same server(AWS EC2 Instance)

I am trying to connect MSSQL database as my second database in Laravel, In the core PHP file It works fine but when I try to connect in the laravel It throws an error.
Here is my .env
MSSQL_CONNECTION=sqlsrv
MSSQL_DATABASE_URL='/EC2AMAZ-61LPEGK\SQLEXPRESS'
MSSQL_HOST=XX.XX.X.XXX
MSSQL_PORT=1433
MSSQL_DATABASE="/dbcrm"
MSSQL_USERNAME="sauser"
MSSQL_PASSWORD='dbpassword123'
MSSQL_TRUSTSERVER='yes'
MSSQL_ENCRYPT=False
MSSQL_STRICT=false
and here is my laravel database config:
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('MSSQL_DATABASE', '/EC2AMAZ-61LPEGK\SQLEXPRESS'),
'host' => env('MSSQL_HOST', 'XX.XX.X.XXX'),
'port' => env('MSSQL_HOSTDB_PORT', '1433'), //I had tried null
'database' => env('MSSQL_DATABASE', '/dbcrm'), //tried without '/'
'username' => env('MSSQL_USERNAME', 'sauser'),
'password' => env('MSSQL_PASSWORD', 'dbpassword123'),
'trust_server_certificate' => env('MSSQL_TRUSTSERVER', 'yes'), //tried 'no'
'encrypt' => env('MSSQL_ENCRYPT', False), //tried true
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
],
Here is the PHP file code which works fine and connect the database as well as execute the query,
$host ="XX.XX.X.XXX";
$username ="sauser";
$password ="dbpassword123";
$database ="dbcrm";
$params = [
"UID" => $username,
"PWD" => $password,
"Database" => $database,
"TrustServerCertificate" => "yes",
];
if(sqlsrv_connect($host, $params)) {
echo "connected..";
} else {
echo "Connection could not be established.<br />";
echo "<pre>";
die( print_r( sqlsrv_errors(), true));
echo "</pre>";
}
I am using the same server for both cases and I have installed/enabled SQLSRV. Please find the phpinfo screenshots for reference.
Why it is working in PHP file but not in the Laravel. Please help.
Note : MSSQL database is installed on another AWS windows Instance and TCP is enabled, and port number is 1433
Here is the error what I am getting,
Finally, able to figure out the issue, Posting the same so it will help someone who has struck for days and ripping their hair out to find the solution.
Change the below .env variables and database config as below,
MSSQL_ENCRYPT=yes
MSSQL_TRUSTSERVER=True
config/database.php
'trust_server_certificate' => env('MSSQL_TRUSTSERVER', true), //Some libraries accessing ODBC/JBDC require Yes/No settings, others True/False,
'encrypt' => env('MSSQL_ENCRYPT', 'yes'), //same here try Yes/No or True/False

Be able to change database connection in runtime with Laravel

So I am making a web application which should be able to upload any SQL statement to any server listed in the database on a schedule. It should connect to the database, execute the statement and make a report based on the information received. Then it can disconnect.
Currently, I have a job in place and it grabs all the information required from the database eg. host, port, DBName etc. I just need to form a connection and then execute the statement.
I am using the Laravel framework.
Edit: I cant modify any database configs as the database information is stored in a table, not a config file.
Thanks
You can set it at runtime this way:
$connKey = 'CustomConnection';
$dbInfo = DatabaseInfo::find($databaseId);
Config::set('database.connections.' . $connKey, array(
'driver' => 'mysql',
'host' => $dbInfo->hostName,
'database' => $dbInfo->database,
'username' => $dbInfo->username,
'password' => $dbInfo->password,
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => '',
));
// Now you can set the new connection to the models
$myModel = new MyModel;
$myModel->setConnection($connKey);
// Or you can use it this way too:
$users = DB::connection($connKey)->select(...);
// Or, also:
$pdo = DB::connection($connKey)->getPdo();
I solved this in a very similar way to one posted :
$connectionName = Crypt::encryptString(str_random(80));
DB::purge("$connectionName");
Config::set("database.connections.$connectionName", [
"driver" => "$Driver",
"port" => "$Port",
"host" => "$Host",
"database" => "$DBName",
"username" => "$UserName",
"password" => "$Password"
]);
$query = DB::connection("$connectionName")->select($statement);
$query= json_decode( json_encode($query), true);
Excel::create("$filename-$mytime", function($excel) use ($query, $filename) {
$excel->sheet("$filename", function($sheet) use ($query){
$sheet->fromArray($query);
});
})->store('xls', storage_path('excel/exports'));
This creates a new connection with a random name (so when in a queue if multiple are executed they wont purge the same database), assigns the details to it, executes the select statement which is defined in the variable $statement. Then creates an excel spreadsheet from that.

Having trouble with sqlsrv on CentOS 7. Looking for assistance or possibly ODBC alternative

I'm having a try at connecting to a MSSQL DB using PHP on a Linux system.
Using tsql -S <dbConfig> or tsql -H <dbHost> successfully connects to the database (with user credentials of course). However, using the same host and config within PDO returns a failed to connect to host adapter error.
The issue seems to be living somewhere between PHP PDO and, I'm assuming freetds.
The debug looks like this:
PDOException in Connector.php line 55:
SQLSTATE[01002] Adaptive Server connection failed (MYHOST.database.windows.net) (severity 9)
in Connector.php line 55
at PDO->__construct('dblib:host=MYHOST.database.windows.net;dbname=RecipeDB;charset=utf8', 'MYUSER#MYHOST', 'MYPASSWORD', array('0', '2', '0', false)) in Connector.php line 55
at Connector->createConnection('dblib:host=MYHOST.database.windows.net;dbname=RecipeDB;charset=utf8', array('driver' => 'sqlsrv', 'host' => 'MYHOST.database.windows.net', 'database' => 'RecipeDB', 'username' => 'MYUSER#MYHOST', 'password' => 'MYPASSWORD', 'charset' => 'utf8', 'prefix' => '', 'name' => 'remoteRecipes'), array('0', '2', '0', false)) in SqlServerConnector.php line 32
at SqlServerConnector->connect(array('driver' => 'sqlsrv', 'host' => 'MYHOST.database.windows.net', 'database' => 'RecipeDB', 'username' => 'MYUSER#MYHOST', 'password' => 'MYPASSWORD', 'charset' => 'utf8', 'prefix' => '', 'name' => 'remoteRecipes')) in ConnectionFactory.php line 61
at ConnectionFactory->Illuminate\Database\Connectors\{closure}()
It seems I'd managed to remove the line containing [global] from my /etc/freetds.conf file. Once I replaced it PDO was able to make a call to the database.
Below is what it looks like for me:
[global]
# TDS protocol version
; tds version = 4.2
tds version = 8.0
client charset = UTF-8
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
dump file = /tmp/freetds.log
debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
[testConnection]
host = MYHOST.database.windows.net
port = 1433
tds version = 8.0

Using different databases based on user request

I've installed Laravel-4 and jenssegers / Laravel-MongoDB which has the same interface to Eloquent model as Laravel, so everything is pretty transparent and 1 database connection works OK.
what I'm trying to do, is switch to another database based on user request (Consider it as API that decided where to go and grab data).
This is what I did:
App::before(function($request)
{
$dbPrefix = $request->segment(1);
if (!is_null($dbPrefix)) {
$dbName = strtolower($dbPrefix);
$newDb = DB::connection('mongodb_'.$dbName);
}
});
From here.. I don't know what to do.. Is it connected to new database that way? how do I tell my Laravel to use $newDb when I refer to DB constant in Models?
But I want it to happen before application starts, so specifying "$connection" variable in model or using explicit call to other database like DB::connection('mongodb2')->query(...) is no good for me.
Thanks
The solution to this would be:
/app/filters.php:
App::before(function($request)
{
$dbPrefix = $request->segment(1);
if (!is_null($dbPrefix)) {
$connectionName = 'mongodb_'.strtolower($dbPrefix);
Config::set('database.default', $connectionName);
}
});
/config/database.php:
'mongodb_soccer' => array(
'driver' => 'mongodb',
'host' => 'localhost',
'port' => 27017,
'username' => 'user',
'password' => 'password',
'database' => 'SoccerData'
),
'mongodb_tennis' => array(
'driver' => 'mongodb',
'host' => 'localhost',
'port' => 27017,
'username' => 'user',
'password' => 'password',
'database' => 'TennisData'
)
Requests:
site.com/soccer
will get connection mongodb_soccer
site.com/tennis
will get connection mongodb_tennis
You can pre-authorize it in default "admin" database where your users are stored, and then switch to any database connection per user request to get the actual data.
I needed it this way for API development.
Good luck

Making CakePHP work with SQL server 2008

I can call SQL server 2008 from PHP with Microsoft Drivers for PHP for SQL Server But as Sqlsvr driver class is needed to use CakePHP with SQL server 2008, I got the driver file from following repository.
However, when running my test cakephp with following database.php
<?php
class DATABASE_CONFIG {
var $default = array(
'driver' => 'sqlsvr',
'host' => 'localhost\EPHP',
'login' => 'sa',
'password' => 'xxxxxxx',
'database' => 'Blog',
);
}
?>
I got following error:
Fatal Error (256): ConnectionManager::loadDataSource - Unable to import DataSource class .DboSqlsvr [CORE\cake\libs\model\connection_manager.php, line 185]
Then I have read all the you-cannot-make-cakePHP-work-with-sql-2008 discussions. Is there any resolution by now?
UPDATE: Let me rephrase my question. I would appreciate if someone successfully made CakePHP work with SQL 2008 and tell me the procedure he followed to do that.
After some research, I found this article ( http://book.cakephp.org/view/1652/Plugin-DataSources-and-Datasource-Drivers). Basically, you can not place your driver file in the directory ( \cakephp\cake\libs\model\datasources\dbo) where the "factory" driver files are located. Instead you should place the driver file in following directory of your baked cake.
your-cake-application\plugins\your-plugin-name\models\datasources\dbo
And then you should change your database.php in config accordingly.
<?php
class DATABASE_CONFIG {
var $default = array(
'driver' => 'your-plugin-name.DboSqlsrv',
'host' => 'localhost\EPHP',
'login' => 'sa',
'password' => 'xxxxxxx',
'database' => 'Blog',
);
}
?>
After this, I could run my cakephp app.
Assuming you have the datasources in the folder app/model/datasource/dbo_sqlsrv.php load it like this:
<?php
class DATABASE_CONFIG {
var $default = array(
'datasource' => 'sqlsvr',
'host' => 'localhost\EPHP',
'login' => 'sa',
'password' => 'xxxxxxx',
'database' => 'Blog',
);
}
?>
The difference is in the 'driver' vs 'datasource' keyword

Categories