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
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;
}
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();
}
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();
});
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;
}
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;
}
}