I want to connect multiple databases with PHP.
I have table which has a connection parameters, i want to show you codes first.
class someClass {
protected $db, $arrayb;
public function __construct() {
include 'db.php';
$this->db = $db;
$this->arrayb = $arrayb;
}
public function prepareSites() {
$prepareSites = $this->db->prepare("SELECT id FROM sites WHERE site_type='somesites' ORDER BY id ASC");
$prepareSites->execute();
$getCountOpSites = $countOpSites->rowCount();
$prepareSites = $prepareSites->fetchAll(PDO::FETCH_ASSOC);
$arraycount = array();
foreach ($prepareSites as $a) {
$arraycount[] = $a;
}
$arrayb = array();
foreach ($arraycount as $b) {
$arrayb[] = $b["id"];
}
$arrayb;
}
Everything is fine in these codes. $arrayb variable gives me every id, i have no problem with arrays.
But,
public function connectSites() {
$dbarray = array();
$i = 0;
foreach ($this->arrayb as $a) {
$i++;
$conn.$i = $this->db->prepare("SELECT * FROM sites WHERE id='{$a}'");
$conn.$i->execute();
$conn.$i = $conn.$i->fetch(PDO::FETCH_ASSOC);
$asd.$i = $conn.$i["id"];
$host2 = $conn.$i["site_host"];
$name2 = $conn.$i["site_name"];
$user2 = $conn.$i["site_user"];
$pass2 = $conn.$i["site_pass"];
$this->dbop.$i = new PDO('mysql:host='.$host2.';dbname='.$name2.'', ''.$user2.'', ''.$pass2.'');
$this->dbop.$i->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->dbop.$i->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbarray[] = $this->dbop.$i;
}
return $dbarray;
}
Number of added connection won't be known. That's why i wanted to add $i variable to make different connections as many as i want. But $dbarray variable gives me nothing. And i don't know how to control it if it gives me anything.
Thank You.
Related
I am trying to test a few scripts that I would normally get from an SQL database but for testing offline I am just creating an array.
Here is what I have right now;
$result = array
(
array("name"=>"Toby", "q1"=>"1"),
array("name"=>"Phelps", "q1"=>"1"),
array("name"=>"Davies", "q1"=>"1"),
array("name"=>"Keith", "q1"=>"1"),
);
$resultnum = count($result);
echo "<b>Question 1</b> <br/><br/>";
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$name = $row['name'];
$answer = $row['q1'];
$q1answer = 1;
if($answer == $q1answer) {
echo $name . " got this right! <br/>";
} else {
echo $name . " got this wrong! <br/>";
}
}
}
How can I get this to work the same as though it was getting the array from an SQL query instead of just my array, for some reason I can't find a way to get this to run.
You can wrap the array in an anonymous class. Single uses like this are a main reason they exist.
$result = new class {
private $data = array
(
array("name"=>"Toby", "q1"=>"1"),
array("name"=>"Phelps", "q1"=>"1"),
array("name"=>"Davies", "q1"=>"1"),
array("name"=>"Keith", "q1"=>"1"),
);
private $data_index = 0;
public $num_rows;
public function __construct() {
$this->num_rows = count($this->data);
}
public function fetch_assoc() {
if (isset($this->data[$this->data_index])) {
$index = $this->data_index++;
return $this->data[$index];
}
}
};
Similar to the earlier answer, I propose a class. Here I would actually name the class, and pass the data to the constructor. The iteration over the array can be done with the current and next methods:
class ResultSet {
private $array = [];
public $num_rows = 0;
public function __construct($data) {
$this->array = $data;
$this->num_rows = count($this->array);
}
public function fetch_assoc() {
$val = current($this->array);
next($this->array);
return $val;
}
}
Until there it would be fixed. You would play with the data in the following:
$result = new ResultSet([
["name"=>"Toby", "q1"=>"1"],
["name"=>"Phelps", "q1"=>"1"],
["name"=>"Davies", "q1"=>"1"],
["name"=>"Keith", "q1"=>"1"],
]);
I did not implement support for count($result) as I don't think that is supported on real mysqli result sets either. You get the count via ->num_rows (like you also do).
I'm in a situation where I want to build a code which gets $bindParam variable in this format:
$bindParams = [$type1 => $param1, $type2 => $param2, ... ]
I wanna build some code that dynamically adds that parameters to the prepared statement.
This is the code which I built so far :
$mysql = new mysqli("localhost", "root", "", "db1");
$stmt = $mysql->prepare($sql);
foreach($bindParams as $type => $data) {
$stmt->bind_param($type, $data);
}
$stmt->execute();
$result = $stmt->get_result();
// and after perhaps twiddling with the result set, but this is not the case .....
For your instance
$sql = "INSERT INTO table1 (name, age) VALUES (?,?);"
and
$bindParams = ["s" => "hello", "i" => 15]
This does not always have this structure and it can change to for example $bindParams = ["s" => "hello", "i" => 15, "d" => 22.5] and so the $sql changes respectively.
After the first time the compiler heads to $stmt->bind_param($type, $data); firefox flushes this error:
Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement in D:\PHP\tr.php on line 23
I know PDO support that as stated here at the end of the page. but perhaps as you might expect Im not a fan of PDO so ;)
My other option is to use the eval() workarounds available in php but thats out of what I might think of.
Is there another way to do this?
I had the same problem, and found an answer much simplier:
$array_of_values = array( "Brasil", "Argentina" );
$types = "ss";
$mysqli_stmt->bind_param( $types, ...$array_of_values );
This is called "argument unpacking", and is available since PHP 5.6
http://php.net/manual/pt_BR/migration56.new-features.php
Sadly mysqli doesn't support this. Calling the function over and over again overwrites the values, so you're only binding one param when you clearly have more.
There's a couple of ways to get around this
Switch to PDO. You can make one bind per function call with that
Bind the params as one aggregate using call_user_func_array
$sqltype = '';
$sqldata = [];
foreach($bindParams as $type => $data) {
$sqltype .= $type;
$sqldata[] = &$data; // MUST be a reference
}
array_unshift($sqldata, $sqltype); // prepend the types
call_user_func_array([$stmt, 'bind_param'], $sqldata);
I use something like this to do dynamic procedure calls.
Example Call:
$mapi = new MySQLIAPI($con);
$mapi->BeginProc();
$mapi->AddParameter("user", $usern, "s");
$mapi->AddParameter("email", $email, "s");
$mapi->AddParameter("passwd", $pwd, "s");
$id = $mapi->CallProc("ij_create_user");
$id = $id[0];
if(isset($id['mysql_error']) || isset($id["error"])){
return "error";
}
return $id["id"];
Example Class:
class MySQLIAPI
{
private $con = null;
private $Variables = null;
private $values = null;
private $types = null;
private $vQu = null;
private $stmt = null;
function __construct($dbc)
{
$this->con = $dbc;
$this->Variables = [];
$this->values = [];
$this->types = [];
$this->vQu = [];
}
function BeginProc()
{
$this->stmt = $this->con->stmt_init(); // initialize statement
}
function AddParameter($key, $val, $type)
{
$this->Variables[] = "#" . $key;
$this->values[] = $val;
$this->types[] = $type;
$this->vQu[] = "?";
}
//KeyPair is v = the value, t = the type s or d
function CallProc($Proc) {
$out_var = null;
$call = "";
if(sizeof($this->values) > 0)
$call = "CALL ".$Proc."(".implode(",", (array)$this->vQu).")";
else
$call = "CALL ".$Proc."()";
if($this->stmt->prepare($call));//call stored procedure with database server session variable
{
if(sizeof($this->values) > 0) {
$params = array_merge(array(implode("", $this->types)), $this->values);
call_user_func_array(array($this->stmt, 'bind_param'), $this->refValues($params));
}
$this->stmt->execute();
$result = $this->stmt->get_result();
/* Error Checking */
$mySQLiError = mysqli_stmt_error($this->stmt);
if ($mySQLiError != "") {
$this->resetStmt();
$this->stmt->close();
$this->stmt = null;
return array('mysql_error' => $mySQLiError);
}
while ($row = $result->fetch_array(MYSQLI_ASSOC))
{
$out_var[] = $row;
}
$result->free();
while($this->stmt->more_results())
{
$this->stmt->next_result();
}
$this->resetStmt();
$this->stmt->close();
$this->stmt = null;
}
return $out_var;
}
private function refValues($arr)
{
if (strnatcmp(phpversion(), '5.3') >= 0) //Reference is required for PHP 5.3+
{
$refs = array();
foreach ($arr as $key => $value)
$refs[$key] =& $arr[$key];
return $refs;
}
return $arr;
}
private function resetStmt()
{
//Reset Params
$this->Variables = array();
$this->values = array();
$this->types = array();
$this->vQu = array();
}
}
What is the proper way to create a function to get array values from a query? I am getting "Undefined index: page_title" error.
However I can get the value without function like: echo $row->page_title;
Or echo $query[0]->title;
function get_page($id) {
$db = new DB();
$query = $db->get_rows("SELECT * FROM pages WHERE id = :id ", array('id' => $_GET['id']) );
foreach ($query as $row) {
$page_id = $row->id;
$page_title = $row->title;
}
return $query;
}
$page = get_page(1);
echo $page['page_title'];
here is my database class:
function get_rows($query, $values=array(), $fetchType = FETCH_OBJ)
{
$sth = $this->dbh->prepare($query);
if(is_array($values) && (sizeof($values) > 0))
{
foreach($values as $key=>$val)
{
$key = is_numeric($key) ? ($key + 1) : $key;
$sth->bindValue($key,$val);
}
}
if($sth->execute())
return $sth->fetchAll($fetchType);
}
To make the function reusable, I would rewrite it the following way
function get_page($id, $col) {
$db = new DB();
$query = $db->prepare('SELECT * FROM pages WHERE id = :id');
$query->execute(array(':id' => $id));
$results = $query->fetch(PDO::FETCH_NUM);
return $results[0][$col];
}
$page = get_page(1, 'page_title');
echo $page;
I skipped the foreach as you said that all id's are unique so you should only ever have 1 result
Also it may not be a bad idea to add some error checking to make sure you do get back what you expect from the query and to make sure it is not empty.
Edit: Sorry if the syntax is a little off, dont have anything to test the code against quickly.
im trying assign values to my variables in ascript by calling a function and variables from another script, but currently im getting errors saying
Undefined property: stdClass::$Boys in
Undefined property: stdClass::$Girls in
im calling a function in a script called report.php from my script
report.php
public function projectReport($ID){
$get_con = $this->getConnection();
$result = mysql_query($query, $get_con);
$rep = new stdClass();
if(false !== $result){
$multis = array();
while($row = mysql_fetch_array($result, MYSQL_ASSOC)){
$count = new stdClass();
$count->Boys = (int)$row['males'];
$count->Girls = (int)$row['females'];
$multis[] = $count;
}
$rep->multiples = $multis;
}
return $rep;
}
function body of my script
$report = new Report();
$log = $report->projectReport($ID);
if($log != false){
$Boys = $log->Boys;
$Girls = $log->Girls;
print_r($Boys);
print_r($Girls);
}
return $log;
your $log can never be false so you don't need to check that. Alhtough multiples attribute might be missing.
Try this:
$report = new Report();
$log = $report->projectReport($ID);
if(property_exists($log, 'multiples')){ //check if multiples attribute exists
foreach ($log->multiples as $m) //walk through every multiples record
{
$Boys = $m->Boys; //get Boys and Girls attributes values and print them
$Girls = $m->Girls;
print_r($Boys);
print_r($Girls);
}
}
I'm pretty sure that's not what you wanna achieve, but that how it should work based on what you've got so far.
Below is my class.
class MaterialType {
public $id;
public $name;
function getAllMaterialType() {
$query = "SELECT * FROM material_types";
$result = mysql_query($query);
$arr = array();
while ($row = mysql_fetch_array($result)) {
$arr[] = new MaterialType();
$arr[]->id = $row['m_type_id'];
$arr[]->name = $row['m_type_name'];
}
return $arr;
}
}
The problem is when I create object in an array like above, and display it using foreach,
there are errors that say Undefined property stdClass. I already defined the property that being used, so why these errors appear? Below is the code that I use to
display data.
$materialTypeObj = new MaterialType();
foreach($materialTypeObj->getAllMaterialType() as $mat) {
echo $mat->name;
}
Every time you do $array[] = it inserts a new element in the end of an array. What you need to do is:
class MaterialType {
public $id;
public $name;
function getAllMaterialType() {
$query = "SELECT * FROM material_types";
$result = mysql_query($query);
$arr = array();
while($row = mysql_fetch_array($result)) {
$mat = new MaterialType();
$mat->id = $row['m_type_id'];
$mat->name = $row['m_type_name'];
$arr[] = $mat;
}
return $arr;
}
}