PHP class: Unable to access array in another function - php

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
}

Related

Calling a method on array iteration, from an object - PHP

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;

How can I change existing function in a class

I have a form class and I want define different functions when form be submitted.
<?php
class Forms {
function __construct() {
if (!empty($_POST['exampleInput'])) {
$this->PostedForms();
}
}
function __call($func, $param) {
}
function PostedForms() {
if (!empty($_POST['exampleInput'])) {
if (function_exists($this->userDefined)) {
$this->userDefined();
}
}
}
}
$form = new Forms();
$form->userDefined = function ($param) {
print_r($_POST);
}
?>
I want define userDefined function outside of class. How can I do this? Can I change any function of class after class was called? Can I change userDefined = function ($param) {print_r($_GET);} for example?

Pass variables from class instance to its extended method

I'm trying to pass a variable to a method in an extended class, but it's not working.
Here's the sample code:
class set2 extends set1
{
function Body($variable) {
}
}
$start2 = new set2();
$start2->Body('some text');
The last line is the part I'm trying to get to work. I'm not sure if I should have a constructor instead to do it or how it's best to get it to work.
I figured it out. I just added a public variable instead and passed its value like this:
class set2 extends set1
{
public $variable = NULL;
function Body() {
echo $this->variable;
}
}
$start2 = new set2();
$start2->variable = 'Some Text';
Three different ways of doing what I think you're trying to do:
class set1
{
protected $headVariable;
function Head() {
echo $this->headVariable;
}
function Body($variable) {
echo $variable;
}
function Foot() {
echo static::$footVariable;
}
}
class set2 extends set1
{
protected static $footVariable;
function Head($variable) {
$this->headVariable = $variable;
parent::Head();
}
function Body($variable) {
parent::Body($variable);
}
function Foot($variable) {
self::$footVariable = $variable;
parent::Foot();
}
}
$start2 = new set2();
$start2->Head('some text');
$start2->Body('some more text');
$start2->Foot('yet more text');

Is it possible to make a names of the tables in the database as a methods of my class?

I am very like to use PDO, so it might be on.
Usage could be as:
$m = new MDB();
$m->Users()->GetRec($param);
Users() is a name of table in the database, GetRec($param) is my function.
A way I go looking like this:
class MDB extends DB {
function __construct(){
parent::__construct();
if ($result = $this->pdo->query("SHOW TABLES"))
{
while ($row = $result->fetch(PDO::FETCH_NUM))
{
// this is only my imagination (not working at all)
__set($row[0],true);
}
}
}
// set
public function __set($name, $value)
{
// here could be a method (not properties)
$this->$name = $value;
}
Sure it's all seems not exactly what I want. So I am able to get some suggestions and advices in this question.
upd 1.
Thanks for the magic method __call and now I'm trying to make it within. Watch my updated code:
class MDB extends DB {
function __construct(){
parent::__construct();
}
public function __call( $method, $param )
{
$tables = array();
if ($result = $this->pdo->query("SHOW TABLES"))
{
while ($row = $result->fetch(PDO::FETCH_NUM))
{
$tables[] = $row[0];
}
}
if (in_array($method,$tables))
{
return $this;
}
else
{
return FALSE;
}
}
Well, seems it works for me!
Yes it's possible! The wrong row in your code is:
__set($row[0],true);
There you should call:
$this->$row[0] = true;
Take a look a the simple example below and at the overloading documentation of PHP http://www.php.net/manual/en/language.oop5.overloading.php.
class A{
//The array which will contain your data
private $tables;
function __construct($array){
$counter = 1;
foreach($array as $value){
//That's the right call!
$this->$value = $counter++;
}
}
function __set($name, $value){
$this->tables[$name] = $value;
}
function __get($name){
if (array_key_exists($name, $this->tables)) {
return $this->tables[$name];
}
}
}
$array = array('a1', 'a2', 'a3', 'a4', 'a5');
$a = new A($array);
foreach($array as $key){
echo $a->$key;
}
Hope this help!

Using SQL function from SQL handling class in other functions

I have created an SQL function SQLquery in a class called SQLHandling
It looks like this:
/***********************************************************
* SQLquery takes a full SQL query and runs it
* If it fails it will return an error otherwise it will return
* the SQL query as given.
************************************************************/
function SQLquery($query) {
$q = mysql_query($query);
if(!$q) {
die(mysql_error());
return false;
} else {
return $q;
}
}
Is there anyway I can use this function in other classes functions without adding
$db = new SQLHandling();
$db->SQLquery($sql);
In every function where I will use it.
I know I can run SQLHandling::SQLquery($sql); but I am trying to avoid that.
use inheritance
refer:
http://php.net/manual/en/language.oop5.inheritance.php
but still you will need to use parent::fun() or $this->fun()
or put it as a public function then use any where.
example:
<?php
function c()
{
echo "moi";
}
class b extends a
{
public function d(){
parent::c();//Hai
$this->c();//Hai
c();//moi
}
}
class a{
public function c(){
echo "Hai";
}
}
$kk = new b();
$kk -> d();
?>
You could instantiate SQLHandling on class level, like so:
private $db;
public function __construct()
{
$this->db = new SQLHandling();
}
public function x()
{
$this->db->query('X');
}

Categories