I'm not particularly familiar with php, and I'm having trouble understanding what's happening. Using a condensed skeleton of what I have:
class Helper
{
public function __construct($value)
{
$this->value = $value;
//etc
}
private function prefix($val)
{
return '1234' . $val;
}
private function otherFunction()
{
$this->value->someFunction(function ($err, $result) {
if($err !== null) {
echo $err->getMessage();
}
return $result;
});
}
public function help()
{
echo $this->prefix('5678'); //outputs 12345678
echo is_null($this->otherFunction()); //outputs 1
}
}
Why does otherFunction return null? I can echo $result right before the return and see what I'm expecting, but it's null afterwards.
Your otherFunction() doesn't return anything. Probably you echo $result inside of the callback function passed to $this->value->someFunction().
Add return just before $this->value->someFunction(... to return the value from otherFunction().
I have this code in my model file
function exist_kode($kode = 1)
{
$get = $this->db->query("SELECT * FROM perkiraan WHERE kode_perk='$kode'");
if($get->num_rows() == 0)
{
return $kode;
}
else
{
$this->exist_kode((int)$kode+1);
}
}
This function is not return some values when I use. But if I change return to echo, it will write the value I hope.
How can i solve this?
Return in your else statement as well:
return $this->exist_kode((int)$kode+1);
Below is my code where I am calling three methods from three models to retrieve counts as below.
$this->load->model('orders_model');
$order_count = $this->orders_model->count_orders(array("executive_id" => $this->id));
$this->load->model('activities_model');
$activity_count = $this->activities_model->count_activities(array("users_id" => $this->id));
$this->load->model('leads_model');
$leads_count = $this->leads_model->count_leads(array("users_id" => $this->id));
And this is the query I am getting:
SELECT COUNT(*) AS numrows FROM orders, activities, leads WHERE executive_id = '5' AND users_id = '5' AND users_id = '5'
which leads to a database error
Why is this happening?
Orders_model
class Orders_model extends CI_Model {
public function __construct() {
$this->load->database();
}
public function get_orders($order_id = FALSE) {
if ($order_id === FALSE) {
$query = $this->db->get('orders');
return $query->result();
}
$this->db->where('id', $order_id);
$query = $this->db->get('orders');
return $query->result();
}
public function add_order($order_data = FALSE) {
if (!$order_data === FALSE) {
if (is_array($order_data)) {
return $this->db->insert('orders', $order_data);
} else {
return false;
}
} else {
return false;
}
}
public function update_order($order_update_data = FALSE, $order_update_condition = FALSE) {
if (!($order_update_data === FALSE && $order_update_condition === FALSE)) {
if (is_array($order_update_data) && is_array($order_update_condition)) {
return $this->db->update('orders', $order_update_data, $order_update_condition);
} else {
return false;
}
} else {
return false;
}
}
public function get_custom_orders($order_custom_condition = FALSE) {
if (!$order_custom_condition === FALSE) {
if (is_array($order_custom_condition)) {
#echo "Yes a parameter is passed which is also an array";
$this->db->where($order_custom_condition);
$query = $this->db->get('orders');
return $query->result();
}
}
}
public function get_last_ref_id() {
$query = $this->db->query('select sprx_ref_id from orders where id in (select max(id) from orders)');
foreach ($query->result() as $row) {
return $row->sprx_ref_id;
}
}
public function fetch_orders($limit, $start, $order_custom_condition) {
$this->db->limit($limit, $start);
$this->db->order_by("id", "desc");
$this->db->where($order_custom_condition);
$query = $this->db->get();
return $query->result();
}
public function count_orders($order_custom_condition) {
$this->db->where($order_custom_condition);
return $this->db->count_all_results('orders', FALSE);
}
}
Activities_model
class Activities_model extends CI_Model {
public function __construct() {
$this->load->database();
}
public function get_activities($activity_id = FALSE) {
if ($activity_id === FALSE) {
$query = $this->db->get('activities');
return $query->result();
}
$this->db->where('id', $activity_id);
#$this->db->order_by('id','ASC');
$query = $this->db->get('activities');
return $query->result();
}
public function add_activity($activity_data = FALSE) {
if (!$activity_data === FALSE) {
if (is_array($activity_data)) {
return $this->db->insert('activities', $activity_data);
} else {
return false;
}
} else {
return false;
}
}
public function update_activity($activity_update_data = FALSE, $activity_update_condition = FALSE) {
if (!($activity_update_data === FALSE && $activity_update_condition)) {
if (is_array($activity_update_data) && is_array($activity_update_condition)) {
return $this->db->update('activities', $activity_update_data, $activity_update_condition);
} else {
return false;
}
} else {
return false;
}
}
public function get_custom_activities($activity_custom_condition = FALSE) {
if (!$activity_custom_condition === FALSE) {
if (is_array($activity_custom_condition)) {
#echo "Yes a parameter is passed which is also an array";
$this->db->where($activity_custom_condition);
$query = $this->db->get('activities');
return $query->result();
}
}
}
public function fetch_activities($limit, $start, $custom_condition) {
$this->db->limit($limit, $start);
$this->db->order_by("id", "desc");
$this->db->where($custom_condition);
$query = $this->db->get();
return $query->result();
}
public function count_activities($custom_condition) {
$this->db->where($custom_condition);
return $this->db->count_all_results('activities', FALSE);
}
}
Leads_model
class Leads_model extends CI_Model {
public function __construct() {
$this->load->database();
}
public function get_leads($lead_id = FALSE) {
if ($lead_id === FALSE) {
$query = $this->db->get('leads');
return $query->result();
}
$this->db->where('id', $lead_id);
$query = $this->db->get('leads');
return $query->result();
}
public function add_lead($lead_data = FALSE) {
if (!$lead_data === FALSE) {
if (is_array($lead_data)) {
return $this->db->insert('leads', $lead_data);
} else {
return false;
}
} else {
return false;
}
}
public function update_lead($lead_update_data = FALSE, $lead_update_condition = FALSE) {
if (!($lead_update_data === FALSE && $lead_update_condition)) {
if (is_array($lead_update_data) && is_array($lead_update_condition)) {
return $this->db->update('leads', $lead_update_data, $lead_update_condition);
} else {
return false;
}
} else {
return false;
}
}
public function get_custom_leads($lead_custom_condition = FALSE) {
if (!$lead_custom_condition === FALSE) {
if (is_array($lead_custom_condition)) {
#echo "Yes a parameter is passed which is also an array";
$this->db->where($lead_custom_condition);
$query = $this->db->get('leads');
return $query->result();
} else {
return false;
}
} else {
return false;
}
}
public function fetch_leads($limit, $start, $lead_custom_condition) {
$this->db->limit($limit, $start);
$this->db->order_by("id", "desc");
$this->db->where($lead_custom_condition);
$query = $this->db->get();
return $query->result();
}
public function count_leads($lead_custom_condition) {
$this->db->where($lead_custom_condition);
return $this->db->count_all_results('leads', FALSE);
}
}
As far as i understand, you are surprised why the query builder uses additional parameter from the previous query.
You've to reset your Query according to docs
which means all your "count_" functions should be like
public function count_leads($lead_custom_condition) {
$this->db->where($lead_custom_condition);
return $this->db->count_all_results('leads');
}
obviously you did set the false flag on purpose - but i'm not sure why ;)
I believe that the error message is only a symptom, not the actual cause of the issue
. The way I read your code is that the count_*() methods in each of the 3 models should return the count from their respective tables only.
However, the way you wrote your count functions results in the query builder adding the tables and conditions to the overall query, not executing them just on the single tables
$this->db->where($custom_condition); <-- this adds a new where condition using "and" operator
return $this->db->count_all_results('activities', FALSE); <-- just adds another table without resetting the others
I would add a $this->db->reset_query(); line as the 1st line in each of the 3 count_*() methods to force the query builder to start from scratch.
The problem is due to using the second argument to $this->db->count_all_results(). When you set the second argument to FALSE then $this->db will not clear any select statements from its cache. Then each successive call to count_all_results() will include the table from any prior call to the function. The solution is simple - don't use the second parameter.
Change
return $this->db->count_all_results('activities', FALSE);
to
return $this->db->count_all_results('activities');
Not related to your problem but something that will improve your code is changing this
public function get_orders($order_id = FALSE) {
if ($order_id === FALSE) {
$query = $this->db->get('orders');
return $query->result();
}
$this->db->where('id', $order_id);
$query = $this->db->get('orders');
return $query->result();
}
to
public function get_orders($order_id = NULL) {
if (!empty($order_id))
{
$this->db->where('id', $order_id);
}
$query = $this->db->get('orders');
return $query->result();
}
Changing the argument default to NULL and using !empty($order_id) helps because it protects against and empty string or empty array being given as the argument. (Ready about empty() here.)
This new logic also keeps the code DRY - your not repeating the two line of code to get and return results.
Many of your other model functions could be cleaner too. For instance
public function add_order($order_data = FALSE) {
if (!$order_data === FALSE) {
if (is_array($order_data)) {
return $this->db->insert('orders', $order_data);
} else {
return false;
}
} else {
return false;
}
}
would be cleaner written like this
public function add_order($order_data = NULL) {
if (!empty($order_data) && is_array($order_data))
{
return $this->db->insert('orders', $order_data);
}
return false;
}
Sorry for nitpicking your code - I couldn't help myself.
I'm trying to write some classes which pull my data out of my database and create objects based on that data. I'm working with CodeIgniter.
The problem is that if an id is supplied to the __construct method but no row in the database table has that id, an object is returned but with all the properties set to NULL.
Is there a way that I can check this and return NULL instead of an object if there is no corresponding row?
class JS_Model extends CI_Model
{
protected $database_table_name;
protected $database_keys;
...
public function __construct($id = NULL){
if($id){
$this->getFromDatabase($id);
}
}
...
function getFromDatabase($id){
foreach($this->database_keys as $key){
$this->db->select($key);
}
$this->db->from($this->database_table_name);
$this->db->where('id', $id);
$this->db->limit(1);
$q = $this->db->get();
if ($q->num_rows() > 0){
foreach($q->result() as $property){
foreach($property as $key => $value){
$this->$key = $value;
}
}
} else {
// NEED TO SET THE OBJECT TO NULL FOR THIS CASE
}
}
...
}
Any help would be appreciated.
This is not possible, once __construct is called, you will receive an object instance.
The correct way to handle this is to throw an Exception from inside the constructor.
class JS_Model extends CI_Model
{
protected $database_table_name;
protected $database_keys;
public function __construct($id = NULL){
if($id){
$row = $this->getFromDatabase($id);
if (!$row) {
throw new Exception('requested row not found');
}
}
}
}
try {
$record = new JS_Model(1);
} catch (Exception $e) {
echo "record could not be found";
}
// from here on out, we can safely assume $record holds a valid record
why dont you make your constructor private and use a method such as GetInstance(); something like this. Syntax may be incorrect as i dont write much php anymore :-(.
class JS_Model extends CI_Model
{
protected $database_table_name;
protected $database_keys;
...
private function __construct($id = NULL){
}
public static function GetInstance($id)
{
$x = new JS_Model($id);
$x->getFromDatabase($id);
if(is_object($x))
{
return $x;
}
return null;
}
...
function getFromDatabase($id){
foreach($this->database_keys as $key){
$this->db->select($key);
}
$this->db->from($this->database_table_name);
$this->db->where('id', $id);
$this->db->limit(1);
$q = $this->db->get();
if ($q->num_rows() > 0){
foreach($q->result() as $property){
foreach($property as $key => $value){
$this->$key = $value;
}
}
} else {
return null;
}
}
...
}
So I'm trying to create a tree structure in PHP. I don't know if that's possible and I'm not all that great with PHP so this is difficult for me.
The code I have so far is (important stuff only, extra code has been cut out):
abstract class tree_node {
protected $_child_refs = array();
abstract public function add_child($arg);
public function count() {
return count($this->_child_refs);
}
public function get_deepest_children() {
if ($this->count() === 0) {
return $this;
} else {
foreach ($this->_child_refs as $child_ref) {
$deepest[] = $child_ref->get_deepest_children();
}
}
}
abstract public function __construct();
}
class data_node extends tree_node {
private $_data = "";
public function add_child($data) {
$new_child = new data_node($data);
$this->_child_refs[] = $new_child;
}
public function __construct($data) {
$this->_data = $data;
}
}
$foo = new data_node("foo");
$foo->add_child("bar");
var_dump($foo->get_deepest_children());
This code should return a data_node with "bar" as the data but instead I get NULL. What's wrong with "return $this"? Is that not the proper way to return an instance of a class itself?
Also, feel free to critique this code/tell me I'm doing this completely wrong. I want to keep tree functions separate from functions specific to the data stored in the tree, which is why I split it up into two classes, but if you think that's a bad idea tell me.
This:
public function get_deepest_children() {
if ($this->count() === 0) {
return $this;
} else {
foreach ($this->_child_refs as $child_ref) {
$deepest[] = $child_ref->get_deepest_children();
}
}
}
Should be something like this:
public function get_deepest_children() {
if ($this->count() === 0) {
return array($this);
}
$deepest = array();
foreach ($this->_child_refs as $child_ref) {
$deepest = array_merge($deepest,$child_ref->get_deepest_children());
}
return $deepest;
}
Your get_deepest_children isn't always returning the same type of value. In the base case it will return a node object, in the other cases it extends the $deepest list but doesn't return any value.
<?php
public function get_deepest_children() {
if ($this->count() === 0) {
return $this;
} else {
foreach ($this->_child_refs as $child_ref) {
$deepest[] = $child_ref->get_deepest_children();
}
}
}
I would modify it like this:
<?php
public function get_deepest_children() {
if ($this->count() === 0) {
return Array($this);
} else {
$deepest = Array();
foreach ($this->_child_refs as $child_ref) {
$deepest = array_merge($deepest, $child_ref->get_deepest_children());
}
return $deepest;
}
}
You should be able to see how it now always it returns an array of all of the deepest nodes (usually called leaf nodes) below/including the current one. This way we can array_merge the consecutive results to get the final ones.