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
Related
I'm wanting to create a new instance of my Class and assign it's attributes the values that are returned. The reason for this is I'm creating a series of methods inheriting from the calling class, as opposed to using static methods which I already had working.
Example of what I'm using currently:
public static function findById($id) {
$id = self::escapeParam($id);
$idVal = is_int($id) ? "i" : "s";
$sql = "SELECT * FROM ".static::$db_table." WHERE id = ? LIMIT 1";
return static::findByQuery($sql,$idVal,$id);
}
public static function findByQuery($sql,$bindChar = '',$bindVal = '') {
try {
$callingClass = get_called_class();
$object = new $callingClass;
$statement = Database::$connection->prepare($sql);
if(!empty($bindChar)) :
$statement->bind_param($bindChar, $bindVal);
endif;
if($statement->execute()) :
$result = $statement->get_result();
$object = $result->fetch_object();
endif;
$statement->close();
if(!empty($object)) :
return $object;
endif;
} catch(Exception $e) {
}
}
What I tried was writing an instantiation method that creates a new instance of my class, and then assign each attribute of the object the value it returns from an array from a tutorial I did. However, the tutorial was fairly outdated and didn't use any new syntax or binding, so I was trying to rework this.
Example from the tutorial below:
public static function find_by_id($id) {
global $database;
$the_result_array = static::find_by_query("SELECT * FROM " . static::$db_table . " WHERE id = $id LIMIT 1");
return !empty($the_result_array) ? array_shift($the_result_array) : false;
}
public static function find_by_query($sql) {
global $database;
$result_set = $database->query($sql);
$the_object_array = array();
while($row = mysqli_fetch_array($result_set)) {
$the_object_array[] = static::instantation($row);
}
return $the_object_array;
}
public static function instantation($the_record){
$calling_class = get_called_class();
$the_object = new $calling_class;
foreach ($the_record as $the_attribute => $value) {
if($the_object->has_the_attribute($the_attribute)) {
$the_object->$the_attribute = $value;
}
}
return $the_object;
}
private function has_the_attribute($the_attribute) {
return property_exists($this, $the_attribute);
}
What I was trying to do from the tutorial, was to return my result as an array using a while, and then assigning a variable by passing the built array into the static::instantation() method, but it doesn't seem to ever be working correctly, as any public functions I create in my calling class (Admin for example) aren't called after as they don't exist due to the Class not being instantiated.
mysqli_result::fetch_object() accepts the class name as the first argument. You can pass the class name as an argument to that method and get the instance of the model. I am not sure why you have that much code but consider my example which I wrote based on your own code:
<?php
class Model
{
public static function findByQuery(string $sql, ?string $bindChar = null, ?string $bindVal = null): ?static
{
$statement = Database::$connection->prepare($sql);
if ($bindChar) :
$statement->bind_param($bindChar, $bindVal);
endif;
$statement->execute();
$result = $statement->get_result();
return $result->fetch_object(static::class);
}
}
class User extends Model
{
private $id;
}
class Database
{
public static mysqli $connection;
}
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Database::$connection = new mysqli('localhost', 'user', 'password', 'test');
$user = User::findByQuery('SELECT ? as id', 's', 'Dharman');
var_dump($user);
The output from that example is:
object(User)#4 (1) {
["id":"User":private]=>
string(7) "Dharman"
}
As you can see, the code created an instance of the class using late-static binding and it also assigned the value to a private property, which you can't do otherwise.
P.S. My example is a little bit tidier. I added parameter typing and removed a lot of unnecessary code. In particular, I remove empty try-catch which is a terrible practice.
I have now got this working, although I feel this is probably not the best way of doing it.
I'm primarily front end so please comment if there are improvements or best practices.
public static function findByQuery($sql,$bindChar = '',$bindVal = '') {
try {
$statement = Database::$connection->prepare($sql);
if(!empty($bindChar)) :
$statement->bind_param("$bindChar", $bindVal);
endif;
if($statement->execute()) :
$result = $statement->get_result();
$output = $result->fetch_object();
endif;
$statement->close();
if(!empty($output)) :
$class = get_called_class();
$object = new $class;
foreach(get_object_vars($output) as $key => $value) :
$object->$key = $value;
endforeach;
endif;
if(!empty($object)) :
return $object;
endif;
} catch(Exception $e) {
}
}
My initial thoughts were declaring an object and then I thought that the PHP fetch_object call would have just assigned my object it's properties after initiating the Class but that wasn't the case.
So what I've done is that if the statement is successful and a results object is created, I then get the object properties and values with the get_object_vars() command, and then loop through these as a key value pair, assigning each attribute it's returned value.
I can confirm this works as I can now run $admin->remove() from my removal script, as opposed to what I was having to do before which was Admin::remove($id);
I have a problem with classes in PHP, I want to assign values received from the database to a private variable so that I can then use them in class functions. But in doing so I get the error:
Fatal error: Constant expression contains invalid operations in ..\database.php on line 21
Here is my code:
class Ustawienia {
private $current_id = $_SESSION['user_id'];
private $uprawnienia = get_premissions(); //here i get a fatal error
private function get_premissions() {
$query_premissions = OpenCon()->prepare("SELECT * FROM uprawnienia WHERE id_pracownicy = :id");
$query_premissions -> bindValue(':id', $current_id, PDO::PARAM_INT);
$query_premissions -> execute();
return $query_premissions -> fetch();
}
public function dostep_ustawienia() {
if($uprawnienia['dostep_ustawienia']) return true;
return false;
}
}
I tried to change return to echo but i didn't helped.
How can i achieve that? Thanks for any help.
You need to assign data directly to private variable
$this->uprawnienia = $query_premissions->fetch();
And then use this private variable:
if($this->uprawnienia['dostep_ustawienia']) return true;
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 can't make a simple echo.
I have an admin.class.php
public static function get_quota() {
return self::find_by_sql("SELECT * FROM quota");
}
public static function find_by_sql($sql="") {
global $database;
$result_set = $database->query($sql);
$object_array = array();
while ($row = $database->fetch_array($result_set)) {
$object_array[] = self::instantiate($row);
}
return $object_array;
}
And my echo code in index.php
<?php
$admin = User::find_by_id($_SESSION['user_id']);
$admin_class = new Admin();
$get_quota = Admin::get_quota();
$sql = "SELECT * FROM quota";
$get_quota = Admin::find_by_sql($sql);
?>
.
.
.
<?php echo $get_quota->daily_a; ?>
So my problem is, that the code is not working. I cannot echo my data. Can you help me, please?
You have a couple of problems here:
<?php echo $get_quota->daily_a; ?>
This line references the $get_quota variable and searches for a member field daily_a. Try this:
<?php echo "Quota is:".var_export($get_quota->daily_a,true); ?>
This will show that that is simply an empty variable.
However, also note:
$get_quota = Admin::get_quota();
$sql = "SELECT * FROM quota";
$get_quota = Admin::find_by_sql($sql);
Here you are calling two separate methods from Admin and setting the variable $get_quota to the result. The second overwrites the first. Therefore the get_quota() method doesn't help us here: we need to know what your find_by_sql() method returns.
EDIT (Post new code added to question)
You can implement logging/echoing within the function you've a problem with:
public static function find_by_sql($sql="") {
global $database; //Note this is bad practice (1).
$result_set = $database->query($sql);
echo "Result Set: ".var_export($result_set,true)."\n";//This should return something if you're getting something back from the database. Also, remove this for runtime (obviously).
if (count($result_set) <= 0) { //constraint checking is always good! And cheap!
error_log("An unexpected number of rows (0) was received from the database for query='".$sql."'.");
}
$object_array = array();
while ($row = $database->fetch_array($result_set)) {
$object_array[] = self::instantiate($row); //Ensure that the instantiate function returns something!
}
echo "Object Array: ".var_export($object_array, true)."\n";//double-check your instantiate function is working
return $object_array;
}
Based on this code, your problem is likely with the instantiate function; if it's not returning anything, $object_array is probably empty. (But not null!).
(1) You should avoid grabbing global variables like this. Instead, instantiate a class that holds and manages your database connection. Then make your find_by_sql function non-static and have a member field pointing to your database.
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();