I have been working on AMFPHP + codeigniter + flash and everything was working just fine but, when I created a stored procedure the problem started. I was able to call the stored procedure with multiple result sets from the AMF browser but whenever the function was called from the flash itself it raises the Bad Version error.
Below is the library {from CI forum} to traverse multiple result sets am using
class Mydb
{
private $CI, $Data, $mysqli, $ResultSet;
/**
* The constructor
*/
function __construct()
{
$this->CI =& get_instance();
$this->Data = '';
$this->ResultSet = array();
$this->mysqli = $this->CI->db->conn_id;
}
public function GetMultiResults($SqlCommand)
{
/* execute multi query */
if (mysqli_multi_query($this->mysqli, $SqlCommand)) {
$i=0;
do
{
if ($result = $this->mysqli->store_result())
{
while ($row = $result->fetch_assoc())
{
$this->Data[$i][] = $row;
}
mysqli_free_result($result);
}
$i++;
}
while ($this->mysqli->next_result());
}
return $this->Data;
}
}
and calling it like this:
$this->load->library('mydb');
$this->mydb->GetMultiResults("CALL test()");
I have noticed that the library loading line raises the Bad Version error at flash end as if I comment out this line it works {works like no error is ther but SP doesn't execute}
Any Idea on how to fix this strange issue.
Although CodeIgniter uses mysqli driver the next_result() method is not set in the DB_driver.
Here and here you can find further details. The idea is:
define next_result() method in system/database/DB_driver.php:
function next_result()
{
if (is_object($this->conn_id))
{
return mysqli_next_result($this->conn_id);
}
}
(be sure to push this up to your notes pile for the CI system core upgrade )
make sure you are using mysqli drive (application/config/database.php)
In your model after you call your stored procedure and BETWEEN each fetch of results use $query_or_somethig-else->next_result(); (and use $query_or_somethig-else->free_result(); in the final)
I have been working on multiple query execution in store procedure in codeigniter
I created a library named SP.php. Here is the code also change in config to database =
mysqli
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class CI_SP {
private $CI;
function __construct() {
$this->CI = & get_instance();
}
public function GetResults($SqlCommand) {
$k = 0;
$arr_results_sets = array();
/* execute multi query */
if (mysqli_multi_query($this->CI->db->conn_id, $SqlCommand)) {
do {
$result = mysqli_store_result($this->CI->db->conn_id);
if ($result) {
$l = 0;
while ($row = $result->fetch_assoc()) {
$arr_results_sets[$k][$l] = $row;
$l++;
}
}
$k++;
} while (mysqli_next_result($this->CI->db->conn_id));
return $arr_results_sets;
}
}
}
and the model code is
$result = $this->sp->GetResults("call function(parameters);
$result1 = $this->sp->GetResults("call function(parameters));
print_r($result);
print_r($result1);
exit;
return $query->result_array();
Related
Hi i am using foreach in php oops to output data from the mysqlbut each data outputs twice please check my code and help it i have tried but no correct result
Here is the code below i have used
class getdata extends db{
public function getdata(){
$sql = "SELECT * FROM users";
$results = $this->connect()->query($sql);
$numrows = $results->num_rows;
if($numrows > 0){
while($row = $results->fetch_assoc()){
$data[] = $row;
}
return $data;
}
else{
echo 'no values';
}
}
}
class showusers extends getdata{
//show users
public function showusers(){
$datas = $this->getdata();
foreach($datas as $data){
echo $data['id'].'<br>';
echo $data['name'].'<br>';
}
}
}
$showusers = new showusers();
$showusers->showusers();
Don't give your function the same name as your class.
With $showusers = new showusers(); you are already executing the showusers function.
To cite php.net:
For backwards compatibility with PHP 3 and 4, if PHP cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class.
Source:https://www.php.net/manual/en/language.oop5.decon.php
So your function showusers() is treated as a constructor for your showusers class and therefore is executed twice. Once when you create an object of the class and once when you call the method.
your code is a bit convoluted I'd suggest passing the database connection object rather than extending continiously.
In this case your constructor showUsers() outputs a list of users. therefore it repeats because you are calling this function twice.
$showusers = new showusers(); // prints users
$showusers->showusers(); // prints users again
move your display function
class showusers extends getdata{
$data;
//initialize
public function showusers(){
$this->data = $this->getdata();
}
//show users
public function displayUsers(){
foreach($this->data as $data){
echo $data['id'].'<br>';
echo $data['name'].'<br>';
}
}
}
$showusers = new showusers();
$showusers->displayUsers();
I'm wondering how to receive the results from a function "from the class itself". An example of this is the PDO functions, where I can do the following to get i.e. the last ID:
$db->query($sql);
$id = $db->lastInsertId();
Right now I have to do the following:
$newThread = $forums->newThread('title','category');
$id = $newThread['id'];
Of course this works great, but I have to use the variable $newThread, which I don't want to. How do I save the value in order to call it later?
In case you have problems understanding how the PDO version works, it's roughly like this:
class PDO {
private $lastInsertId;
public function query($sql) {
magic_sql_api_call($sql);
/* here be dragons */
$this->lastInsertId = magic_sql_api_get_last_insert_id();
}
public function lastInsertId() {
return $this->lastInsertId;
}
}
You can create code like this
class Forums {
private $id;
...
function createTread($title, $category) {
$newThread = $forums->newThread($title, $category);
$this->id = $newThread['id'];
}
function lastId() {
return $this->id;
}
}
You can use it
$forums->createTread('title','category');
$id = $forums->lastId();
You probably will need to save $newThread in property too.
I am trying to make a 1 on 1 chat website by learning as I progress, but I've come to a hault.
I can't write to the database.
I have four php files linked below.
Index
Init:
session_start();
define('LOGGED_IN', true);
require 'classes/Core.php';
require 'classes/Chat.php';
?>
Chat
Core:
class Core {
protected $db, $result;
private $rows;
public function __construct() {
$this->db = new mysqli("localhost","root","");
}
public function query($sql) {
$this->result = $this->db->query($sql);
}
public function rows() {
for($x = 1; $x <= $this->db->affected_rows; $x++) {
$this->rows[] = $this->result->fetch_assoc();
}
return $this->rows;
}
}
?>
I have a MySql database set with WAMP.
P.S. Yes, I have opened the "< ? php"
but it doesn't get displayed here.
From what I have seen you do not select a default database. You must either give a default database in
$this->db = new mysqli("localhost","root","", "mydatabase");
or select one later with
$this->db->select_db("mydatabase");
You also don't check the return values of the mysql calls. For example, add
public function query($sql) {
$this->result = $this->db->query($sql);
if ($this->result === false) {
echo $this->db->error;
}
}
after your mysql statements, in order to see whether the statements succeed or fail.
For debugging purposes you can display the sql and corresponding result
public function query($sql) {
var_dump($sql);
$this->result = $this->db->query($sql);
var_dump($this->result);
echo $this->db->error;
}
Can anyone see why my check_multi function would return a --
Fatal error: Call to undefined function check_multi() in
/var/www/vhosts/aero.onelinksoftware.com/application/models/Design.php
on line 21
The above error shows up and I am not sure what I am doing wrong. I tried setting my function as public, private, static, and other combinations but no matter what I try; the system still errors out. Can you not call a function inside a Model in Zend? I don't understand why I cannot use a function I created if it is inside a class I made.
If I echo and die before the check_multi call; I can see my text and such. I have also performed a php test for syntax and it is valid as far as it reports.
class Model_Design
{
/**
* Constructs our partials.
*
* #return void
*/
public function __construct($key)
{
// Get the DB Connection
$db = Zend_Registry::Get('db');
// Setup the SQL Statement
$sql = $db->select()->from('design', array('id'));
// Get the Result
$result = $sql->query();
// Get our Row
$row = $result->fetchAll();
if(check_multi($key, $row)) {
echo "omg"; die();
}
// Make sure the id isn't empty
if (empty($key)) {
throw new Exception('You have a disturbing lack of variables.');
}
// Store the id
$this->variables = $key;
// Construct our query
$sql = $db->select()->from('design')->where('`id` = ?', $key);
// Get the result
//$result = $sql->query();
//$row = $result->fetch();
}
private function check_multi($n, $arr)
{
foreach ($arr as $key => $val) {
if ($n===$key) {
return $key;
}
}
return false;
}
}
Try:
$this->check_multi($key, $row);
To access a variable or function from inside its container class you must use $this. $this is the current instance of the class.
How do you call the function ? use $this->check_multi($n,$arr); or you can try function_exists() to check if function really exist
I am working with lemonade-php. My code is at https://github.com/sofadesign/limonade.
The issue I am having is when I try to run
class syscore {
public function hello(){
set('post_url', params(0));
include("./templates/{$this->temp}/fullwidth.tpl");
return render('fullwidth');
}
}
which then loads the fullwidth.tpl and runs function fullwidth
fullwidth.tpl
<?php
global $post;
function fullwidth($vars){
extract($vars);
$post = h($post_url);
}
print_r($this->post($post));
?>
it seems to pass the $post_url but I can not pass it again to the print_r($this->post($post));
However when I try to run print_r($this->post($post)) inside the fullwidth function it says it can not find the post() function
I have tried a number of things like below
function fullwidth($vars){
extract($vars);
$post = h($post_url);
print_r(post($post));
}
I tried re connecting to the syscore by
$redi = new syscore();
$redi->connection() <-- this works
$redi->post($post) <-- this does not
Here is my full class syscore
class syscore {
// connect
public function connect($siteDBUserName,$siteDBPass,$siteDBURL,$siteDBPort, $siteDB,$siteTemp){
for ($i=0; $i<1000; $i++) {
$m = new Mongo("mongodb://{$siteDBUserName}:{$siteDBPass}#{$siteDBURL}:{$siteDBPort}", array("persist" => "x", "db"=>$siteDB));
}
// select a database
$this->db = $m->$siteDB;
$this->temp = $siteTemp;
}
public function hello(){
set('post_url', params(0));
include("./templates/{$this->temp}/fullwidth.tpl");
return render('fullwidth');
}
public function menu($data)
{
$this->data = $data;
$collection = $this->db->redi_link;
// find everything in the collection
//print $PASSWORD;
$cursor = $collection->find(array("link_active"=> "1"));
if ($cursor->count() > 0)
{
$fetchmenu = array();
// iterate through the results
while( $cursor->hasNext() ) {
$fetchmenu[] = ($cursor->getNext());
}
return $fetchmenu;
}
else
{
var_dump($this->db->lastError());
}
}
public function post($data)
{
$this->data = $data;
$collection = $this->db->redi_posts;
// find everything in the collection
//print $PASSWORD;
$cursor = $collection->find(array("post_link"=> $data));
if ($cursor->count() > 0)
{
$posts = array();
// iterate through the results
while( $cursor->hasNext() ) {
$posts[] = ($cursor->getNext());
}
return $posts;
}
else
{
var_dump($this->db->lastError());
}
}
}
It looks like you are having some issues understanding the execution path that PHP is taking when trying to render your template. Let's take a more in-depth look, shall we?
// We're going to call "syscore::hello" which will include a template and try to render it
public function hello(){
set('post_url', params(0)); // set locals for template
include("./templates/{$this->temp}/fullwidth.tpl"); // include the template
return render('fullwidth'); // Call fullwidth(array('post_url' => 'http://example.com/path'))
}
The trick to solving this one is to understand how PHP include works. When you call include("./templates/{$this->temp}/fullwidth.tpl") some of your code is executing in the scope of the syscore object, namely:
global $post;
and
print_r($this->post($post));
fullwidth is created in the global scope at this point, but has not yet been called. When render calls fullwidth you're no longer in the syscore scope, which is why you cannot put $this->post($post) inside without triggering an error.
Ok, so how do we solve it? Glad you asked.
We could probably refactor syscore::post to be a static method, but that would then require syscore::db to be static, and always return the SAME mongodb instance (singleton pattern). You definitely do not want to be creating 1000 Mongo instances for each syscore instance.
We could just abuse the framework. A much poorer solution, but it will get the job done.
fullwidth.tpl
<?php
function fullwidth($vars){
$post_url = ''; // put the variables you expect into the symbol table
extract($vars, EXTR_IF_EXISTS); // set EXTR_IF_EXISTS so you control what is added.
$syscore_inst = new syscore;
$post = h($post_url);
print_r($syscore->post($post)); // I think a puppy just died.
}
Look the second way is a complete hack, and writing code like that will probably mean you won't get promoted. But it should work.
But let's say you wanted to get promoted, you would make good, shiny code.
// Note: Capitalized class name
class Syscore {
protected static $_db;
public static function db () {
if (! static::$_db) {
static::$_db = new Mongo(...);
}
return static::$_db;
}
// #FIXME rename to something more useful like "find_posts_with_link"
public static post($url) {
$collection = static::db()->redi_posts;
// find everything in the collection
$cursor = $collection->find(array("post_link"=> $url));
// Changed to a try-catch, since we shouldn't presume an empty find is
// an error.
try {
$posts = array();
// iterate through the results
while( $cursor->hasNext() ) {
$posts[] = ($cursor->getNext());
}
return $posts;
} catch (Exception $e) {
var_dump($this->db->lastError());
}
}
}
Then in your fullwidth function, we don't have to do any of that stupid nonsense of treating an instance method like it were a static method.
function fullwidth($vars){
$post_url = ''; // put the variables you expect into the symbol table
extract($vars, EXTR_IF_EXISTS); // set EXTR_IF_EXISTS so you control what is added.
$post = h($post_url);
print_r(Syscore::post($post)); // static method. \O/ Rainbows and unicorns.
}