PHP Error: Trying to get property of non-object - php

I am working in CodeIgniter framework and I have tried to apply all the other solutions I found on stack but I could not make it work so here is my problem...
I am trying to retrieve a record from MySQL database table called 'questions' based on uri segment. Then I am trying to display this record in a view. As far as I can tell, the uri segment is passed along everywhere it needs to be, and record is retrieved from database.
The problem comes up when I am trying to access the data from the controller, in my view.
Error I am getting for each echo in my loop in 'view_thread_view' is
A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: views/view_thread_view.php
Any solutions would be greatly appreciated.
Here is my code:
Controller thread
function view_thread()
{
$quest = $this->uri->segment(3);
echo $quest;// for checking if uri segment is passed
if($query = $this->data_model->get_thread($quest))
{
$data['records'] = $query;
}
$this->load->view('view_thread_view', $data);
Model data_model
public function get_thread($quest)
{
if($q = $this->db->get_where('questions' , 'qid' , $quest));
{
return $q;
}
}
View view_thread_view
<div title="question_view">
<h1>Question View<h1>
<?php foreach($records as $data) : ?>
<div>
<h2>Title</h2>
<?php
echo $data->title;
?>
</div>
<div>
<h2>Question</h2>
<?php
echo $data->contents
?>
</div>
<div>
<h2>Tags</h2>
<?php
echo $data->tags
?>
</div>
<div>
Thread owner
<?php
echo $records->uname
?>
</div>
<?php endforeach; ?>
</div>
EDIT: QUESTION ANSWERED
Thanks to Girish Jangid fixed the problem this is the working code:
Controller
function view_thread()
{
$quest = $this->uri->segment(3);
echo $quest;// for checking if uri segment is passed
//$data = array();
if($query = $this->data_model->get_thread($quest))
{
$data['records'] = $query;
}
$this->load->view('view_thread_view', $data);
}
Model
public function get_thread($quest)
{
if($q = $this->db->get_where('questions' , array('qid' => $quest)));
{
return $q;
}
}
View
<div title="question_view">
<h1>Question View<h1>
<?php foreach($records->result() as $data) : ?>
<div>
<h2>Title</h2>
<?php
echo $data->title;
?>
</div>
<div>
<h2>Question</h2>
<?php
echo $data->contents
?>
</div>
<div>
<h2>Tags</h2>
<?php
echo $data->tags
?>
</div>
<div>
Thread owner
<?php
echo $data->uname
?>
</div>
<?php endforeach; ?>
</div>
</div>

You should user db function to fetch results, please use CodeIgniter db Query Results functions, like this
if($records->num_rows() > 0){
foreach($records->result() as $data){
if(isset($data->title)) echo $data->title;
}
}
For more detail please read CodeIgniter Query Result function
Query Results
Try this code
<div title="question_view">
<h1>Question View<h1>
<?php if($records->num_rows() > 0) { ?>
<?php foreach($records->result() as $data) : ?>
<div>
<h2>Title</h2>
<?php
echo $data->title;
?>
</div>
<div>
<h2>Question</h2>
<?php
echo $data->contents
?>
</div>
<div>
<h2>Tags</h2>
<?php
echo $data->tags
?>
</div>
<div>
Thread owner
<?php
echo $records->uname
?>
</div>
<?php endforeach; ?>
<?php } ?>
</div>

$records is an array, not an object, therefore you cannot do $records->uname. You probably meant $data there too.
Edit: On second look, it appears $data is an array as well! Arrays are accessed via ['key'] not ->key
Also, your code is way over complicated.
<?php
foreach($records as $data){
$string = <<<STR
<div>
<h2>Title</h2>
{$data['title']}
</div>
...etc
STR;
echo $string;
}
http://www.php.net/manual/en/language.types.string.php

Related

For each inside other for each on view MVC PHP

I'm trying to give structure to my code and i am facing a problem.
I'm looping through a sql query response and for each element i'm trying to retrieve other related elements. It works in my controller without problem but when i'm trying to repeat in the view I always get the same value for the related element
My controller:
<?php
include_once('class/guide.class.php');
$bdd = new DBHandler();
$req = guide::getGuides($bdd,0,5);
foreach ($req as $results => $poi)
{
$req[$results]['id'] = htmlspecialchars($poi['id']);;
$req[$results]['name'] = nl2br(htmlspecialchars($poi['name']));
$guide = new guide($results['name'],$bdd);
$guidePois = $guide->getGuidePois($poi['id']);
foreach ($guidePois as $res => $re)
{
echo $guidePois[$res]['id'];
echo $guidePois[$res]['name'];
$guidePois[$res]['id'] = htmlspecialchars($re['id']);
$guidePois[$res]['name'] = nl2br(htmlspecialchars($re['name']));
}
}
include_once('listing.php');
here, you see that I echo the ids/names of the related list of element and it works well, the output is correct for each element of the first list.
When i do it in my view:
<?php
foreach($req as $poi)
{
?>
<div class="news">
<h3>
<?php echo $poi['id']; ?>
<em>: <?php echo $poi['name']; ?></em>
</h3>
<?php foreach($guidePois as $re)
{
?>
<h4>
<?php echo $re['id']; ?>:
<?php echo $re['name']; ?>
</h4>
<?php
}
?>
</div>
<?php
}
?>
Somehow the first list output are the good elements, but for the 2nd list, i always get the related elements of the first item.
Do you have an idea ?
Thanks a lot for your help
This is because you only set:
$guidePois = $guide->getGuidePois($poi['id']);
once in the controller.
If you want it to work in the view, you need to insert this code right after the closing </h3>
<?php $guidePois = $guide->getGuidePois($poi['id']); ?>
So that $guidePois gets a new value in each iteration.
Complete view code:
<?php
foreach($req as $poi)
{
?>
<div class="news">
<h3>
<?php echo $poi['id']; ?>
<em>: <?php echo $poi['name']; ?></em>
</h3>
<?php
$guidePois = $guide->getGuidePois($poi['id']);
foreach($guidePois as $re)
{
?>
<h4>
<?php echo $re['id']; ?>:
<?php echo $re['name']; ?>
</h4>
<?php
}
?>
</div>
<?php
}
?>

Message: Undefined property: stdClass in codeigniter

I got this error:
A PHP Error was encountered Severity: Notice Message: Undefined property: stdClass::$positionsNum
when i run.
My model:
public function load_job($id){
$Where = array('jobs.id' => $id);
$this->db->select('jobs.id, positionsNum, companyName, contract_type.titleEN as contractType');
$this->db->from('jobs');
$this->db->join('contract_type', 'jobs.contractTypeId = contract_type.id', 'left');
$this->db->where($Where);
$Result = $this->db->get();
return $Result->first_row() ;
}
my view:
<?php if(isset($job) && count($job) > 0){ ?>
<div class="row job-detail-row">
<div class="col-lg-6 job-detail-label"><?php echo lang('contractType'); ?></div>
<div class="col-lg-6"><?php if(isset($job->contractType)) echo $job->contractType; ?></div>
</div>
<div class="row job-detail-row">
<div class="col-lg-6 job-detail-label"><?php echo lang('num_vacancies'); ?> </div>
<div class="col-lg-6"><?php echo $job->positionsNum; ?></div>
</div>
<?php } ?>
my Controller's function:
public function job() {
$job_id = $this->uri->segment(3);
if(isset($job_id) && !empty($job_id))
{
//one job
$job = $this->job_model->load_job($this->GetLang, $job_id);
$data['job'] = $job;
$this->load->view( 'front/singleJob', $data);
}
}
Also, i printed the returned object and it returns this:
stdClass Object(
[id] => 9
[positionsNum] => 2
[companyName] =>
[contractType] => type1
)
But, contractType won't be printed in page even if it is already has a value.
I can't figure out the problem. Any help?
The problem is here.
you have a function with one parameter.
public function load_job($id);
but in controller you are passing two values.
Try to pass correct values.
$job = $this->job_model->load_job($this->GetLang, $job_id);
it should be like this.
$job = $this->job_model->load_job( $job_id);
try like this
public function job() {
$job_id = $this->uri->segment(3);
if(isset($job_id) && !empty($job_id))
{
//one job
$data['job'] = $this->job_model->load_job($this->GetLang, $job_id);
$this->load->view( 'front/singleJob', $data);
}
}
So, it is solved now :)
This problem happened twice in two files:
First is which stated in my question, and I had an error in another query at the same page.
Second problem was in the HTML file. My complete view was like this:
<?php if(isset($service) && count($service) > 0){ ?>
<div class="row job-detail-row">
<div class="col-lg-6 job-detail-label"><?php echo lang('contractType'); ?></div>
<div class="col-lg-6"><?php if(isset($service->contractType)) echo $service->contractType; ?></div>
</div>
<?php } ?>
<ul>
<?php foreach ($similarServices as $service) { ?> <<========= NOTICE: $service here is the same as the above condition
<li>
<div class="title"><?php echo $service->title; ?>
</div>
</li>
<?php }//end foreach similarServices ?>
</ul>
It appeared because i used the same variable name $service, so i changed it and it works now. Hope this helps you.

Trying to get property of non-object in Codeigniter?

My controller code just generate ten copies of the same data. And I put the data in an array of array.Controller Code Below:
for($i=0;$i < $this->per_page;$i++)
{
$temp['title'] = "test";
$temp['link'] = "localhost/cib/index.php";
$temp['month'] = '4';
$temp['day'] = '21';
$temp['authorlink'] = "localhost/cib/index.php/author";
$temp['author'] = "Charles";
$temp['content'] = "tetestersafaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
$results[] = $temp;
}
$data['main_content'] = 'report_list';
$data['posts'] = $results;
$this->load->view('include/templates', $data);
And I show the data generated by controller in the view page report_list, the code of report_list is
<div id="bg_top">
</div>
<div class = "container" id="content">
<div class="row-fluid">
<div class="span9" id="content_left">
<h2>解题报告列表</h2>
<link href="<?php echo base_url('assets/css/style.css') ?>" rel="stylesheet">
<?php if(!empty($posts) && is_array($posts)):?>
<?php foreach($posts as $post):?>
<div class="entry">
<h2 class="entrytitle"><?php echo anchor($post->link, $post->title)?><span></span></h2>
<div class="entrymeta1">
<div class="meta-date">
<span class="meta-month"><?php echo $post->month?></span>
<span class="meta-day"><?php echo $post->day?></span>
</div>
<span class="meta-author"><?php echo anchor($post->authorlink, $post->author)?></span>
<span class="meta-category"></span>
<span class="meta-comment"></span>
<div class="clear"></div>
</div><!-- [entrymeta1] -->
<div class="entrybody">
<p><?php echo $post->content;?><?php echo anchor($post->link, '阅读全文')?></p>
</div>
<div class="entrymeta3">
</div>
</div><!-- [entry] -->
<?php endforeach;?>
<?php endif;?>
</div>
<div class="span3">
<?php echo "hello world2";?>
</div>
</div>
</div>
The question is where am wrong? why is there errors "Trying to get property of non-object"?
I tried to print the data in the controller, it works quite well.
foreach($results as $post)
{
foreach($post as $key=>$value)
{
echo $key.':'.$value;
echo '<br/>';
}
}
You need to print the variables in the view file in array style like this:
<?php echo anchor($post['link'], $post['title'])?>
Still you can always print the array to view the structure:
<?php echo "<pre>";print_r($posts);echo "</pre>";
My assumption is that
You are expecting $posts as array of objects. But in $posts in some loaction there is no object with property month, day etc. So just before the for loop you should look the type of $posts by
var_dump($posts)
This will give you the clear picture about your error
Change all the variables $post->link to array $post['link']
$post->month
$post->day
every fields that are using in template.

Yii: How to update multiple models using only 1 form 1 model and 1 action?

I have a model website and a model url.
Each url data is attached to a website data. A url is related to a website via a website_id.
On my web app, I need to check the data before accepting it.
I want to see on screen the entire data regarding a url data and I managed to do this.
Now, I also want to update the entire data that is listed on screen.
On screen I have the entire url data and website data, but when I try to save the data, the website data is empty.
My logic was to add to the url model a property: public $website;
And within the url model, a method aftersave:
protected function afterSave() {
$w = null;
$w = Website::model()->findByAttributes(array('id' => $this->website_id));
//echo '<pre>';
//print_r($w);
print_r($this->website);
$w->link = $this->website['link'];
$w->domain = $this->website['domain'];
$w->description = $this->website['description'];
$w->save(false);
die;
return parent::afterSave();
}
and here is the important code from the _form file:
<div class="row">
<?php echo $form->labelEx($model,'will_expire'); ?>
<?php echo $form->dropDownList($model,'will_expire',array(0=>'No',1=>'Yes')); ?>
<?php echo $form->error($model,'will_expire'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'link'); ?>
<?php echo $form->textField($model_website,'link'); ?>
<?php echo $form->error($model_website,'link'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'domain'); ?>
<?php echo $form->textField($model_website,'domain'); ?>
<?php echo $form->error($model_website,'domain'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'description'); ?>
<?php echo $form->textField($model_website,'description'); ?>
<?php echo $form->error($model_website,'description'); ?>
</div>
There are few questions:
Is the relation url and website being defined in the model such that $url->website of a existing url gives you valid website record?
You form shows, you are not using any website_id, means that you are creating a new website record for every URL, means $w = Website::model()->findByAttributes(array('id' => $this->website_id)); will always return NULL
I assume you have defined a relation of website within your URL model.
Suggested function from my understanding:
protected function afterSave() {
//data is already assigned by the caller
$w = null;
$w = Website::model()->findByAttributes(array('id' => $this->website_id));
if($w)
{
Yii::log("updating existing website data","info");
$this->website->save();
}
else
{
Yii::log("creating new website data","info");
$this->website->save();
$this->website_id = $this->website->website_id;
$this->update(array('website_id')); //save the relation
Yii::log("created new website {$this->website_id}","info");
}
return parent::afterSave();
}
It turned out to be small mistakes like w instead of W, object property instead of array;
Ok, so let me teach you how to do this;
I have 2 models: Url and Website.
Url model has a foreign key website_id and a relation to model Website;
Within the Url model I have a property called website and i declared it like: public $website = array();;
The data gets added thru a bookmarklet that uses a API so the data will be there when the admin comes to update/check it;
In the Url model i have a method afterSave:
protected function afterSave() {
$w = null;
$w = Website::model()->findByAttributes(array('id' => $this->website_id));
if($w)
{
$w->link = $this->website['link'];
$w->domain = $this->website['domain'];
$w->description = $this->website['description'];
$w->save();
}
return parent::afterSave();
}
where $this->website gets populated in the UrlController on actionUpdate like:
public function actionUpdate($id, $type = 'update') {
$model = $this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['Url'])) {
$model->attributes = $_POST['Url'];
$model->website = $_POST['Website'];
if ($model->save())
if ($type == 'update')
$this->redirect(array('view', 'id' => $model->id));
else
$this->redirect(array('/admin/url/approvePublicLink'));
}
$model_website = Website::model()->findByAttributes(array('id'=>$model->website_id));
$this->render('update', array(
'model' => $model,
'model_website' => $model_website,
));
}
and gets passed to the afterSave method later;
this is the _update view:
<div style="padding:20px 20px;">
<h1>Update Url, Website, Keywords ...</h1>
<?php echo $this->renderPartial('_form', array(
'model'=>$model,
'model_website' => $model_website,
)); ?>
</div>
and this is the _form view that gets rendered partial:
<div class="form">
<?php
$form=$this->beginWidget('CActiveForm', array(
'id'=>'url-form',
'enableAjaxValidation'=>false,
));
?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'website_id'); ?>
<?php echo CHtml::link($model->relation_website->domain,$model->relation_website->domain,array('class'=>'avia','target'=>'_blank')); ?>
<?php echo $form->error($model,'website_id'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'link'); ?>
<?php echo $form->textField($model,'link',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'link'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'title'); ?>
<?php echo $form->textField($model,'title',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'title'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'description'); ?>
<?php echo $form->textField($model,'description',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'description'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'important'); ?>
<?php echo $form->dropDownList($model,'important',array(0=>'Normal',1=>'Important')); ?>
<?php echo $form->error($model,'important'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'views'); ?>
<?php echo $form->textField($model,'views'); ?>
<?php echo $form->error($model,'views'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'created'); ?>
<?php echo $model->created; ?>
<?php echo $form->error($model,'created'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'updated'); ?>
<?php echo $model->updated; ?>
<?php echo $form->error($model,'updated'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'will_expire'); ?>
<?php echo $form->dropDownList($model,'will_expire',array(0=>'No',1=>'Yes')); ?>
<?php echo $form->error($model,'will_expire'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'link'); ?>
<?php echo $form->textField($model_website,'link'); ?>
<?php echo $form->error($model_website,'link'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'domain'); ?>
<?php echo $form->textField($model_website,'domain'); ?>
<?php echo $form->error($model_website,'domain'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'description'); ?>
<?php echo $form->textField($model_website,'description'); ?>
<?php echo $form->error($model_website,'description'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'status'); ?>
<?php echo $form->dropDownList($model,'status',array(-1=>'Banned',0=>'Normal',1=>'Active')); ?>
<?php echo $form->error($model,'status'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
I hope it helps.

Error message keeps coming back saying the array is not defined.

I'm developing a website using Codeigniter. The structure site is simple, I have dynamic menu and content retrieving DB in Model. Then assign a method to call both of them in Controller.
I have that weird error message keeps coming back saying the array is not defined.
I can get tabPhotos, it contains datas.
View:
<div id="container">
<div id="photos">
<?php echo "Count: ". count($tabPhotos); ?>
<ul>
<?php if (!is_array($tabPhotos) || empty($tabPhotos)) :?>
<?php return null; ?>
<?php foreach ($tabPhotos as $item) : ?>
<?php echo "Model: " . $item->url; ?>
<?php endforeach; ?>
<?php endif; ?>
</ul>
</div>
</div>
Controller:
public function loadMenu($file) {
$data['tabMenuItems'] = $this->qdphoto_model->getAllMenuItems();
$this->load->view($file, $data);
}
public function loadCategoryPage($file, $category='Book 1') {
$data['tabPhotos'] = $this->qdphoto_model->getAllPicturesByCategory($category, 'url, model');
$this->load->view($file, $data);
}
Am I reading this correctly? if $tabPhotos IS NOT an array OR it is and it happens to be EMPTY then return null and continue to run the foreach loop with a mysterious endif following?
<?php if (!is_array($tabPhotos) || empty($tabPhotos)) :?>
<?php return null; ?>
<?php foreach ($tabPhotos as $item) : ?>
<?php echo "Model: " . $item->url; ?>
<?php endforeach; ?>
<?php endif; ?>
Shouldn't it read this:
<?php if (is_array($tabPhotos) && !empty($tabPhotos)) :?>
<?php foreach ($tabPhotos as $item) : ?>
<?php echo "Model: " . $item->url; ?>
<?php endforeach; ?>
<?php endif; ?>
no need for that return null statement.
Also, I believe you can return views as strings. If you want to load more than one view you can certainly load any fragment of your view as a string...
$string = $this->load->view($file, $data, true);
Please note that you should review this:
http://codeigniter.com/user_guide/general/views.html
See bottom. It says how to return as string, except that I am used to slightly different syntax thanks to custom controllers and such. Perhaps this example I provided is not accurate.

Categories