Calling php function from inside another function - php

Maybe you guys can help me I am trying to do this:
public function index()
{
$r = array();
//some code
echo json_encode($this->utf8ize($r));
}
public function utf8ize($d) {
//some code
return $d;
}
But I get the "Call to undefined function utf8ize()" error
Why?
Edit 1: The complete code
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Solicitud extends MX_Controller {
public function __construct()
{
/*
parent::__construct();
if(!$this->input->is_ajax_request())
{
show_404();
exit();
}
else
{
*/
$this->load->model('Solicitud_model', 'Model');
//}
}
public function index()
{
$bandera = $this->input->post('bandera');
$r = array();
if ($bandera == 1){
$result = $this->Model->getConsulta($this->session->session_facultad_apps);
$r = array("data" => $result,
"success" => true,
"bandera" => $bandera);
}else if($bandera == 2)
{
$result = $this->Model->get($this->session->session_facultad_apps);
$r = array("data" => $result,
"success" => true,
"bandera" => $bandera);
}else if ($bandera == 3){
$result = $this->Model->getAsigna($this->session->session_facultad_apps);
$r = array("data" => $result,
"success" => true,
"bandera" => $bandera);
}
echo json_encode(utf8ize($r));
}
public function utf8ize($d) {
if (is_array($d)) {
foreach ($d as $k => $v) {
$d[$k] = utf8ize($v);
}
} else if (is_string ($d)) {
$d = iconv('UTF-8', 'ISO-8859-1', $d);
return utf8_encode($d);
}
return $d;
}

this is used to reference the current instance of an object. In your case, you missed the reference to this for the recursive call.
Simple solution - also add $this-> to the inner utf8ize call
echo json_encode($this->utf8ize($r));
...
public function utf8ize($d) {
if (is_array($d)) {
foreach ($d as $k => $v) {
$d[$k] = $this->utf8ize($v);
}
} else if (is_string ($d)) {
$d = iconv('UTF-8', 'ISO-8859-1', $d);
return utf8_encode($d);
}
return $d;
}

It looks as if your code is correct.
However I do not see the class defenition nor can I see you using the class.
I created a class on my local machine that works, when I call the method of the test class the function returns an empty array.
<?php
class Test
{
public function index()
{
$r = array();
echo json_encode($this->utf8ize($r));
}
public function utf8ize($d)
{
//some code
return $d;
}
}
$test = new Test();
echo $test->index();
I hope this helps, if not feel free to reach out :)

Mmm not the best answer but this code works
public function index()
{
$r = array();
//some code
}
function utf8ize($d) {
//some code
}
echo json_encode(utf8ize($r));
}
I had to put the function inside the original function
Edit: The error was from the recursive call; not the first one.
Thanks to all!

Related

what's wrong with my php code with recursive method?

Here is my php code, the test method not giving wanted output, and the other weird thing is var_dump('a') print 3 times;
my wanted output is array('qtggccc','qtff23sdf');
public function main()
{
$serverIds = array('ff23sdf','ggccc');
$res = $this->test($serverIds);
var_dump($res);
}
public function test($serverIds,$imgArray = array())
{
if(count($serverIds) > 0){
$media_id = array_pop($serverIds);
$imgUrl= $this->hh($media_id);
array_push($imgArray,$imgUrl);
var_dump($serverIds);
var_dump($imgArray);
$this->test($serverIds,$imgArray);
}
var_dump('a');
return $imgArray;
}
public function hh($m)
{
return 'qt'.$m;
}
Try this:
class MyClass{
private $imgArray = array();
public function main(){
$serverIds = array('ff23sdf','ggccc');
$res = $this->test($serverIds);
print_r($this->imgArray);
}
public function test($serverIds){
if(count($serverIds) > 0){
$media_id = end($serverIds);
$imgUrl= $this->hh($media_id);
array_push($this->imgArray,$imgUrl);
//remove last element
array_pop($serverIds);
$this->test($serverIds);
}
return;
}
public function hh($m){
return 'qt'.$m;
}
}
$obj = new MyClass();
echo '<pre>';
$obj->main();
Why use recursion? You are using a complicated solution for a simple problem.
public function main()
{
$serverIds = array('ff23sdf','ggccc');
$res = array();
//These three lines replace an entire recursive function, making the code easier and saving a chunk of memory once you start using real arrays
foreach ($serverIds as $media_id){
array_unshift($res, $this->hh($media_id));
}
var_dump($res);
}
public function hh($m)
{
return 'qt'.$m;
}

PHP - What is wrong? Learning MVC - Beginner

Hy,
i started learning PHP and i created a simple MVC Style Codebase.
The Script just generates a random number and displays this numer. I also write a function to display the number shown before but it does not work. The value is empty. Can you help me out, i have no clue whats wrong and there is no php error thrown.
view.php
<?php
class View
{
private $model;
private $view;
public function __construct()
{
$this->model = new Model();
}
public function output()
{
echo 'Current Entry: ';
echo $this->model->getData();
echo '<br />';
echo 'Update';
echo '<br />';
echo 'Last';
}
public function getModel()
{
return $this->model;
}
}
controller.php
<?php
class Controller
{
private $model;
private $view;
public function __construct($view)
{
$this->view = $view;
$this->model = $this->view->getModel();
}
public function get($request)
{
if (isset($request['action']))
{
if ($request['action'] === 'update')
{
for ($i = 0; $i<6; $i++)
{
$a .= mt_rand(0,9);
}
$this->model->setData($a);
}
elseif ($request['action'] === 'preview')
{
$this->model->setLast();
}
else
{
$this->model->setData('Wrong Action');
}
}
else
{
$this->model->setData('Bad Request');
}
}
}
model.php
<?php
class Model
{
private $data;
private $last;
public function __construct()
{
$this->data = 'Default';
}
public function setData($set)
{
if ( ! (($set == 'Wrong Action') && ($set == 'Bad Request')))
{
$this->last = $this->data;
}
$this->data = $set;
}
public function getData()
{
return $this->data;
}
public function setLast()
{
$this->data = $this->last;
}
public function getLast()
{
return $this->last;
}
}
index.php
<?php
require_once 'controller.php';
require_once 'view.php';
require_once 'model.php';
$view = new View();
$controller = new Controller($view);
if (isset($_GET) && !empty($_GET)) {
$controller->get($_GET);
}
$view->output();
Are there any other, bad mistakes in the Script?
Any input very welcome! :)
The problem with your code is that PHP does not preserve variable values between requests, therefore, when you set your $model->last value here:
$this->last = $this->data;
It gets reset on your next request.
You may want to store $last value in a session or a cookie instead. Something like:
$_SESSION['last'] = $this->data;
And then when you are instantiating your model you could initialize it with a value stored in a session if available:
index.php - add session_start() at the beginning
model.php:
public function __construct()
{
$this->data = isset($_SESSION['last']) ? $_SESSION['last'] : 'Default';
}
public function setData($set)
{
$this->data = $set;
if ( ! (($set == 'Wrong Action') && ($set == 'Bad Request')))
{
$_SESSION['last'] = $this->data;
}
}
controller.php
elseif ($request['action'] === 'preview')
{
//Remove this
//$this->model->setLast();
}

Php: turning it into a recursive function

I have currently two classes.
the ArrayCompare class:
<?php
namespace App\Tools\RegexExtract;
class ArrayCompare
{
public function compare(Array $arrayToCompare)
{
$elementData = new ElementMetaData();
$metaData = $elementData->extract($arrayToCompare[0], [], $initial=true);
foreach ($arrayToCompare as $currentElement) {
$metaData = $elementData->extract($currentElement, $metaData);
}
return $metaData;
}
}
which uses the ElementMetaData class
<?php
/**
* A class for extracting meta data from an element.
*/
namespace App\Tools\RegexExtract;
class ElementMetaData
{
public function extract($element, $metaDataToCompare = [], $initial = false)
{
if ($initial == true) {
$this->isInteger($element) ? $returnMetaData['isInteger'] = $this->isInteger($element) : null;
$returnMetaData['length'] = $this->length($element);
}
else {
$returnMetaData=$metaDataToCompare;
if ($returnMetaData != []) {
if (isset ($returnMetaData['isInteger']) && !$this->isInteger($element)) {
unset($returnMetaData['isInteger']);
}
if (isset ($returnMetaData['length']) && $this->length($element) != $returnMetaData['length']) {
unset($returnMetaData['length']);
}
}
}
return $returnMetaData;
}
private function isInteger($element)
{
return is_int($element);
}
private function length($element)
{
return strlen($element);
}
}
the basic functionality is:
given I have an array
$arr=[1,2,3];
I want to get the "similarities" between ALL Elements. According to a an array i Predefine...so this would deliver this result:
$metaArray=['isInteger'=>true,'length'=>1];
and this would deliver just length as similarity:
$arr=[1,2,'D'];
$metaArray=['length'=>1];
While this array would deliver an empty result []
$arr=[1,2,'3D']; // result is [] since not all integers or not all of same length.
Now my solution does not use recursive functions...but I am sure it can be used somehow.
Also, I want to add more "criteria"....So "isEmailAdress", "beginswithA"....etc....and this would make my if statements a horror....so what is the best strategy/design pattern to follow here?
#deceze beat me to it by fair margin... but I'll still post my solution that works basically with the same principles.
abstract class abstractComparer
{
private $array;
private $result = true;
protected $name;
public function compareArray($array)
{
$current = null;
foreach ($array as $index => $value)
{
$this->result = $this->result && $this->compareValues($index, $current, $value);
$current = $value;
}
}
public function getResult()
{
return $this->result;
}
public function getName()
{
return $this->name;
}
public abstract function compareValues($index, $value1, $value2);
public abstract function getSuccessValue();
}
class intComparer extends abstractComparer
{
protected $name = "isInteger";
public function compareValues($index, $value1, $value2)
{
return is_int($value2);
}
public function getSuccessValue()
{
return true;
}
}
class lengthComparer extends abstractComparer
{
protected $name = "length";
protected $length = 0;
public function compareValues($index, $value1, $value2)
{
$this->length = strlen($value2);
return $index == 0 || strlen($value1) == $this->length;
}
public function getSuccessValue()
{
return $this->length;
}
}
And do the actual processing like this:
$temp = [1,2,3];
$comparers = [new intComparer(), new lengthComparer()];
$result = array();
foreach ($comparers as $comparer)
{
$comparer->compareArray($temp);
if ($comparer->getResult())
{
$result[$comparer->getName()] = $comparer->getSuccessValue();
}
}
//var_dump($result);
I don't see any need for recursion here, so I'll just make a suggestion for a design approach:
Implement each criterion as a class:
abstract class Criterion {
protected $valid = true;
abstract public function initialize($value);
abstract public function check($value);
public function isValid() {
return $this->valid;
}
}
class Length extends Criterion {
protected $length;
public function initialize($value) {
$this->length = strlen($value);
}
public function check($value) {
if ($this->length != strlen($value)) {
$this->valid = false;
}
}
}
You then make an array of all your criteria:
$criteria = [new Length, ...];
foreach ($criteria as $criterion) {
$criterion->initialize($values[0]);
}
And slowly whittle them down through your values:
foreach ($values as $value) {
foreach ($criteria as $criterion) {
$criterion->check($value);
}
}
$commonCriteria = array_filter($criteria, function (Criterion $criterion) {
return $criterion->isValid();
});

How to only return an array from this class?

I'm a preocedural programmer, and dont know much about objects.
I have the following class (found it on SO)
class MultiCurl
{
private $allToDo;
private $multiHandle;
private $maxConcurrent = 20;
private $currentIndex = 0;
private $info = array();
private $options = array(CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 1,
CURLOPT_TIMEOUT => 3);
public function __construct($todo, $concurrent)
{
$this->allToDo = $todo;
$this->maxConcurrent = $concurrent;
$this->multiHandle = curl_multi_init();
}
public function process()
{
$running = 0;
do {
$this->_addHandles(min(array($this->maxConcurrent - $running, $this->_moreToDo())));
while ($exec = curl_multi_exec($this->multiHandle, $running) === -1) {
}
curl_multi_select($this->multiHandle);
while ($multiInfo = curl_multi_info_read($this->multiHandle, $msgs)) {
$this->_showData($multiInfo);
curl_multi_remove_handle($this->multiHandle, $multiInfo['handle']);
curl_close($multiInfo['handle']);
}
} while ($running || $this->_moreTodo());
return $this;
}
private function _addHandles($num)
{
while ($num-- > 0) {
$handle = curl_init($this->allToDo[$this->currentIndex]);
curl_setopt_array($handle, $this->options);
curl_multi_add_handle($this->multiHandle, $handle);
$this->info[$handle]['url'] = $this->allToDo[$this->currentIndex];
$this->currentIndex++;
}
}
private function _moreToDo()
{
return count($this->allToDo) - $this->currentIndex;
}
private function _showData($multiInfo)
{
// $this->info[$multiInfo['handle']]['multi'] = $multiInfo;
$this->info[$multiInfo['handle']]['curl'] = curl_getinfo($multiInfo['handle']);
$this->info[$multiInfo['handle']]['content'] = curl_multi_getcontent($multiInfo['handle']);
return $this->info[$multiInfo['handle']];
}
}
When I actually use it:
$concurrent = 20;
$mc = new MultiCurl($nodes, $concurrent);
$output = $mc->process();
print_r($output);
I simply want it to output the multi-dimentional array of all the responses, so only what the "_showData" function returns.
Currently it returns a bunch of other stuff like:
[allToDo:MultiCurl:private] => Array
[multiHandle:MultiCurl:private] => Resource id #11
[maxConcurrent:MultiCurl:private] => 20
[currentIndex:MultiCurl:private] => 100
[info:MultiCurl:private] => Array
I only need the contents of "[info:MultiCurl:private]" array
add public method to class "MultiCurl". for example:
public function getInfo() {
return $this->info;
}
if you don't wanna edit the class file, extend and use it.
Class MultiCurlWrapper extends MultiCurl {
public function getInfo() {
return $this->info;
}
}
In the process method, instead of
return $this;
use
return $this->info;
Would print_r($output[info:MultiCurl:private]); work?
And if the keys of the $output array are always the same, could you access it with
print_r($output[4]);
I would add a method to get what you need as the current function returns the object.
In its simplest form;
public function getInfo()
{
return $this->info;
}

PHP function in a function

I am trying to build a function that will call another function.
For example, if I have an array full of function names to call, is it possible to call a function for every array value without writing it in a script?
Example:
function email($val=NULL) {
if($val)
$this->_email = $val;
else
return $this->_email;
}
function fname($val=NULL) {
if($val)
$this->_fname = $val;
else
return $this->_fname;
}
For email, fname, etc.
But I want to have it like:
function contr_val($key,$val) {
function $key($val=NULL) {
if($val)
$this->_$key = $val;
else
return $this->_$key;
}
function $key($val="hallo");
}
And call it with:
contr_val("email", "test")
You're really trying to create member variables dynamically and retrieve their values. This is what __get() and __set() are for.
Here's how you could use it:
class TestClass {
var $data = array();
public function __set($n, $v) { $this->data[$n] = $v; }
public function __get($n) {
return (isset($this->data[$n]) ? $this->data[$n] : null);
}
public function contr_val($k, $v = NULL) {
if ($v)
$this->$k = $v;
else
return $this->$k;
}
};
$sherp = new TestClass;
$sherp->contr_val("Herp", "Derp");
echo "Herp is: " . $sherp->contr_val("Herp") . "\n";
echo "Narp is: " . $sherp->contr_val("Narp") . "\n";
Something like this:
/*
Input: $val - any value
$varname - the variable name, for instance: _email
*/
function checkValue($val=NULL, $varname) {
if($val)
$this->$var = $val;
else
return $this->$var;
}
checkValue("hello", "_email");
checkValue("hello2", "_name");
If you are doing this for a class, consider using PHP's magic methods __get() and
__set().
In an array full of function names, this calls every function that exists.
ghoti#pc:~$ cat functest.php
#!/usr/local/bin/php
<?php
function one() { print "one\n"; }
function two() { print "two\n"; }
function three() { print "three\n"; }
$a=array( "one", "two", "three", "four" );
foreach ($a as $item) {
if (function_exists($item)) {
$item();
} else {
print "No such function: $item\n";
}
}
ghoti#pc:~$ ./functest.php
one
two
three
No such function: four
ghoti#pc:~$
You need to check if the function exists or not:
function contr_val($key,$val) {
if (!function_exists($key)) {
function $key($val=NULL) {
if ($val)
$this->_$key = $val;
}
}
else {
return $this->_$key;
}
}

Categories