Good morning to everyone here, I try to make a query of the following form with zend framework but I can not, I want to use while because with foreach already do, leave my code to see where I'm wrong:
Model.php
<?php
class Application_Model_Datas
{
public function listar()
{
$db = Zend_Db_Table::getDefaultAdapter();
$select = $db->select()
->from('album');
return $db->fetchAll($select);
}
}
Index.phtml
<?php
//And your view looks like this.
while ($select = $this->datos){
print_r($results);
}
?>
Controller.php
<?php
class IndexController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
$table = new Application_Model_Datas();
$this->view->datos = $table->listar();
}
}
The problem is it does not show me any errors or data or anything
Your code has no sense/effect
<?php
//And your view looks like this.
while ($select = $this->datos){
print_r($results); //Normally you get in an infinite loop
}
?>
You just need to iterate over a simple array :
$i = 0;
while($i < count($this->datos)) {
print_r($this->datos[$i++]); //Getting current element, and incremeting counter
}
Hope it helps.
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 have created one new function in a existing controller, in which I am accessing a model's function which has a query to get the list.
I have loaded the model in controller. This model function works with other function but not working for new created function.
class Cart extends CI_Controller
{
function Cart()
{
parent::__construct();
$this->mdl_common->checkUserSession();
$this->load->model('mdl_friend_web');
$this->load->model('api/mdl_friend','mdl_friend_api');
$this->load->model('mdl_cart_web');
$this->load->library('pagination');
}
//works for this function
function ajax_get_cart_list($offset = 0)
{
is_ajax();
$this->load->model('mdl_cart_web');
$limit = PER_PAGE;
$s_data = $_POST;
$carts = $this->mdl_cart_web->get_cart_list($limit,$offset,$s_data)->result_array();
$totalRows = $this->mdl_cart_web->get_total_cart_product($s_data)->num_rows();
$data = $this->mdl_common->pagination_data('cart/get_cart_list/',$totalRows,$limit,'show_data');
$data['carts'] = $carts;
$data['total_cart'] = $totalRows;
$html = $this->load->view('cart/ajax_cart_list',$data,true);
echo $html;
}
//not working for this
function calculate_distance()
{
$limit = '';
$delivery = 0;
$previousName = '';
$count = 0;
$oneShop = '0';
is_ajax();
// $this->load->model('mdl_cart_web');
$lat1 = $_POST['lat1'];
$long1 = $_POST['long1'];
// $user_id = $_POST['user_id'];
$user_id = $this->session->userdata('user_id');
$carts = $this->mdl_cart_web->get_cart_list($limit,0,'')->result_array();
$response = array();
$data['carts'] = $carts;
foreach($data['carts'] as $row) {
echo $row['store_latitude'];
}
}
model
<?php
class Mdl_cart_web extends CI_Model
{
/*=================================================================================
Get cart list
==================================================================================*/
function get_cart_list($limit,$offset,$data)
{
$this->db->select('c.*,p.*,s.name as store_name,s.latitude as store_latitude,s.longitude as store_longitude,count(r.product_id) as review , IFNULL(AVG(r.star),0) as avg_star,i.*',false);
$this->db->join('p_product as p','c.product_id = p.product_id','left');
$this->db->join('p_product_image as i','c.product_id = i.product_id','left');
$this->db->join('p_product_review as r','c.product_id = r.product_id','left');
$this->db->join('p_store as s','s.store_id = p.store_id','left');
$this->db->limit($limit,$offset);
$this->db->where('c.user_id',$this->session->userdata('user_id'));
$this->db->group_by('c.cart_id');
$this->db->from('p_cart as c');
return $this->db->get();
}
?>
I am not able to get the array data.I can see blank alert.
What is going wrong here? Please help.Thank you.
I think you are writing your query not properly try this:
$this->db->select('c.*,p.*,s.name as store_name,s.latitude as store_latitude,s.longitude as store_longitude,count(r.product_id) as review , IFNULL(AVG(r.star),0) as avg_star,i.*',false);
$this->db->from('p_cart as c');
$this->db->join('p_product as p','c.product_id = p.product_id','left');
$this->db->join('p_product_image as i','c.product_id = i.product_id','left');
$this->db->join('p_product_review as r','c.product_id = r.product_id','left');
$this->db->join('p_store as s','s.store_id = p.store_id','left');
$this->db->limit($limit, $offset);
$this->db->where('c.user_id', $this->session->userdata('user_id'));
$this->db->group_by('c.cart_id');
return $this->db->get();
As Above comment and after seeing your question that the model works fine for the one function and not for the other so I think that loading a model is what you have to look properly.
I see that in your not working function you have noticed some basic problems.
You have commented the model loading code after is_ajax(). // $this->load->model('mdl_cart_web'); so first remove that comment and try again.
Send Correct and proper data to the model. Please Check this below line of code that is executing properly or not.
In Your Not working model.
$carts = $this->mdl_cart_web->get_cart_list($limit,0,'')->result_array();
In Your Working Model:
$carts = $this->mdl_cart_web->get_cart_list($limit,$offset,$s_data)->result_array();
And One thing I want if you are using the same model in more functions in the same controller then you should use __construct()
public function __construct() {
parent::__construct ();
$this->load->model('mdl_cart_web');
}
By adding a model into the __construct() you can use it in the entire controller and all of the functions.
What I'm trying to do, is iterate through an array (Which in my case is a MySql result), and output it, but also do something else with the data at the same.
Doing this using procedural methods is easy - just put it in the foreach loop.
But, I'm wondering if there is a way that it could be integrated into the object.
So, say for example, I wanted to put the first field into a session, I could do this:
<?php
class MyClass {
public $myArray=array();
public function __construct() {
//..
//Mysql query as $stmt
//..
$this->myArray=$stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
$obj=new MyClass;
$i=0;
foreach($obj->myArray as $row) {
?>
<!-- Output HTML formatted data -->
<?
$_SESSION[$i]=$row['firstfield'];
$i++;
}
?>
But, then that takes the task away from the class.
I could put a foreach loop in the class, like so:
<?php
class MyClass {
public $myArray=array();
public function __construct() {
//..
//Mysql query as $stmt
//..
$this->myArray=$stmt->fetchAll(PDO::FETCH_ASSOC);
$i=0;
foreach($this->myArray as $row) {
$_SESSION[$i]=$row['firstfield'];
$i++;
}
}
}
$obj=new MyClass;
foreach($obj->myArray as $row) {
?>
<!-- Output HTML formatted data -->
<?
}
?>
But, now we have 2 loops on the same data-set. Doubling the time to do the same task.
Is there a way to create a method to do something when the array is being looped through? Effectively making it so that the data-set would only have to be looped through once ...
Edit
Also, forgot to mention, the reason I can't build the HTML within the object, is because it will be used on different pages with different HTML layouts.
How about this
<?php
class MyClass {
public $myArray=array();
public $htm = NULL;
public function __construct(&$format=NULL) {
//..
//Mysql query as $stmt
//..
$this->myArray=$stmt->fetchAll(PDO::FETCH_ASSOC);
$i=0;
foreach($this->myArray as $row) {
switch ($format) {
case 'Page1' :
$this->htm .= $this->format1($row);
break;
case 'Page2' :
$this->htm .= $this->format2($row);
break;
default:
$this->htm .= $this->format_default($row);
}
$_SESSION[$i]=$row['firstfield'];
$i++;
}
}
private function format1($row) {
return // formatted html
}
private function format2($row) {
return // formatted html
}
private function format_default($row) {
return // formatted html
}
}
$obj=new MyClass('Page1');
echo $obj->htm;
?>
Alternatively you could subclass MyClass with as many subclasses as you need for the formats you require.
class myBaseClass {
public $myArray=array();
public function __construct() {
//..
//Mysql query as $stmt
//..
$this->myArray=$stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
class format1Class extends myBaseClass
{
public $htm;
public function __construct() {
parent::_construct();
$i=0;
foreach($this->myArray as $row) {
$this->htm .= // format specific to this class
$_SESSION[$i]=$row['firstfield'];
$i++;
}
}
}
class format2Class extends myBaseClass
{
public $htm;
public function __construct() {
parent::_construct();
$i=0;
foreach($this->myArray as $row) {
$this->htm .= // format specific to this class
$_SESSION[$i]=$row['firstfield'];
$i++;
}
}
}
Now depending on which format you require in any script you instantiate the required class.
$obj = new format2Class();
echo $obj->htm;
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.
}
I tried a lot of search but unable to figure out why array $wordlinks in function DoWordLink is not carrying values from function __construct. PHP class code as below:
<?php
class autolinkkeyword
{
public $wordlinks = array();
public function __construct(){
$query = mysql_query("SELECT keyword FROM library");
while ($row = mysql_fetch_array($query))
{
$this->wordlinks [$row["keyword"]] = $row["keyword"];
}
}
public function linkkeywords ($posts)
{
function DoWordLink($match)
{
$rpl=$match[1];
if(isset($wordlinks[$rpl]))
{
$kword = $this->wordlinks[$rpl];
$rpl="<a class=\"keyword_link\" href=\"#\" onclick=\"popup('popUpDiv');
ajax_loadContent('kword', 'library.php?keyword=$kword')\">$kword</a>";
unset($this->wordlinks[$match[1]]);
}
return $rpl;
}
$wl=array_keys($this->wordlinks);
$pm="/((?<=\s|^)(?:" . implode('|',$wl) .")(?=\.|\!|\?|\,|\'|\s|$))/im";
foreach($posts as $key => $mainbody)
{
$mainbody=preg_replace_callback($pm, 'DoWordLink', $mainbody) ;
echo $mainbody;
}
}
}
?>
You can make it an actual method of that class and call it using this method:
http://www.php.net/manual/en/language.pseudo-types.php#language.types.callback
like:
preg_replace_callback($pm, array($this, 'DoWordLink'), $mainbody);
Change DoWordLink function so it is part of the class like:
class autolinkkeyword
{
function DoWordLink($match)
{
$rpl=$match[1];
if(isset($this->wordlinks[$rpl]))
{
$kword = $this->wordlinks[$rpl];
$rpl="<a class=\"keyword_link\" href=\"#\" onclick=\"popup('popUpDiv');
ajax_loadContent('kword', 'library.php?keyword=$kword')\">$kword</a>";
unset($this->wordlinks[$match[1]]);
}
return $rpl;
}
}
aren't you missing a "this->" construct here? if(isset($this->wordlinks[$rpl]))
Use the $this everywhere you refer to $wordlinks.
$this->wordlinks
You need to access the property in your linkkeywords-method with the object-accessor, too!
public function linkkeywords ($posts)
{
// Here use $this->wordlinks not $wordlinks
}