mixed arrays (text and strings) in a php function - php

Im trying to get to grips with php (rather unsuccessfully). I keep getting tripped up on the syntax for defining and calling functions
the code ive written is
$alpha = array(1, "alpha");
$beta = array(2, "beta");
function find_best_provider($provider1, $provider2){
if($provider1 > $provider2){
return array($provider1[0], $provider1[1]);
}
else {
return array($provider2[0], $provider2[1]);
}
}
$winner = find_best_provider($alpha, $beta);
echo $winner;
But i keep getting this notice -
Notice: Array to string conversion in /Applications/MAMP/htdocs/find_best_provier_func.php on line 17
Array
Im aware what the problem is but im not quite sure how to solve it, any helps much appreciated !

If you're trying to evaluate the first element in the array, try this:
function find_best_provider($provider1, $provider2)
{
if($provider1[0] > $provider2[0])
{
return array($provider1[0], $provider1[1]);
}
else
{
return array($provider2[0], $provider2[1]);
}
}

Related

preg_replace n times a matching string?

this should be very simple question, but i cant get it working for some reason, my framework is PHALCON
$string='GuGuSy';
i want this to be replaced as
$output = 'AAB';
so I coded it as:
public function graha($planet)
{
if(strpos($planet,'Sy')!==false){
$planet = preg_replace("/Sy/",'B',$planet);
}
if(strpos($planet,'Gu')!==false){
$planet = preg_replace("/Gu/",'A',$planet);
//str_replace("Gu",'A',$planet);
}
return $planet;
}
but output I get is not correct, why?
My output is for the string is "A" only why ?
Issue was related to the Phalcon framework it self
when you return values it seems to use the last returned value only in VOLT templating system. So what you have to do it echo $planet in the function to get the correct value displayed in the phalcon-volt system.
$string='GuGuSy';
function graha($planet)
{
$a='';
if(strpos($planet,'Sy')!==false){
$a= $planet = preg_replace("/Sy/",'B',$planet); // $planet=GuGuB
}
if(strpos($planet,'Gu')!==false){
$a= preg_replace("/Gu/",'A',$planet);
}
return $a;
}
echo graha($string);

PHP OOP array duplicated in method

Very new to OOP so please bear with me. I have a method that checks characteristics of a persons array and has a counter to keep track of things. The persons array starts off as serialized data, which I'm converting to an array with the unzerialize() function. When I do var_dump($this->people) in the constructor, I get the correct values. When I do the same in any of the other methods in the class, the array is duplicated a number of times and my counter produces incorrect values.
Also doing echo gettype($this->people) in the constructor results in array as expected, but in the other methods results in arrayarrayarrayarray....
What could be causing this duplication? And how do I solve it?
* EDIT *
Sorry for the confusion. I did not know where the problem was so it was difficult for me to explain properly.
The problem is not with my class definition, but how I am using the object. I have reworked the code to illustrate. I thought that once the object was instantiated, the values produced by it would be set, however it turns out that each time I call the get_results() method, $this->num is incremented and the value is persisted.
So my question is, how do I run the get_results() method once, and access the results[] array without changing the values? I was hoping I could do something like if($nums['results']['num'] == 1) but that results in a fatal error.
class DoStuff
{
private $num;
public $results;
public function __construct($val)
{
$this->num = $val;
$this->results = [];
}
private function compute_num()
{
$this->num++;
$this->results['num'] = $this->num;
return $this->results;
}
public function get_results()
{
$this->results = $this->compute_num();
return $this->results;
}
}
$nums = new DoStuff(0);
$nums->get_results();
if($nums->get_results()['num'] == 1)
{
printf('<p>(if) Num is: %d</p>', $nums->get_results()['num']);
}
else
{
printf('<p>(else) Num is: %d</p>', $nums->get_results()['num']);
}
// Prints (else) Num is: 3
Ok, so I was trying to access an object as an array. The solution is to use get_object_vars() after running the get_results() method.
$nums = new DoStuff(0);
$nums->get_results();
$nums = get_object_vars($nums);
if($nums['results']['num'] == 1)
{
printf('<p>(if) Num is: %d</p>', (int) $nums['results']['num']);
}
else
{
printf('<p>(else) Num is: %d</p>', (int) $nums['results']['num']);
}
// Prints: (if) Num is: 1

Populating an Array with recursive function of a class

I'm getting stuck with maybe a simple question. I created a new class with many calculations inside. I have a recursive array to dynamically generate SQL from a Die result. When the result is between a given range, I'll have to do an extra operation.
I've got this multi-dimensional array to fill with the value of my dice, using an array of IDs as my first "key":
$this->multidim[$id_object][]
I was thinking about creating another function to populate it, but I'm unsure how to build it correctly. The specifications of this function I need are the following:
I need to call a function with the multidimensional array, and
If the result is 100, I need to re-roll the dice twice, and check the result again
$this->checkresult($id_obj, $die);
function checkresult($id_obj, $die)
{
if ($die == 100){
$rand1 = $this->launchDie(1, 100);
$rand2 = $this->launchDie(1, 100);
if($this->checkresult($array, $rand1)) {
if($this->checkresult($array, $rand2)) {
return 1;
}
}
} else {
if (!isset($array[$tiro])) {
$this->multidim[$id_obj][$die] = 1;
}
return 1;
}
}
Is this approach correct? I feel uncomfortable not returning a "real" value, but as I said I need to re-call that function recursively.
You can return the rolled value like this:
public function addResult($object_id, $result)
{
$this->multidim[$object_id][] = $result;
}
public function checkResult($object_id)
{
$roll = $this->launchDie(1, 100);
if ($roll == 100) {
$additionalRoll = $this->checkResult($object_id);
$this->addResult($object_id, $additionalRoll);
$roll = $this->checkResult();
}
return $roll;
}
And call it like this:
$this->addResult($object_id, $this->checkResult($object_id));
This way each time a 100 is rolled there will be two rolls instead of the one. Please note that this could go on forever (improbable, though ;)).
Also note that I changed the structure of your multidim array, as it made more sense to me that way, you may need to change that back if it doesn't match what you would like to achieve.

Wonder how codility.com test cases are defined?

I was giving codility.com a try. For the test "PermMissingElem" on https://codility.com/programmers/lessons/1
I wrote a PHP solution which is not very nice, but still works for all my test cases.
Codility only gives me 20% telling me about several test cases that failed. Here are some of them.
For example:
empty_and_single
empty list and single element 0.050 s. RUNTIME ERROR
tested program terminated unexpectedly
stdout:
Invalid result type, int expected.
missing_first_or_last
the first or the last element is missing 0.050 s. RUNTIME ERROR
tested program terminated unexpectedly
stdout:
Invalid result type, int expected.
single
single element 0.050 s. RUNTIME ERROR
tested program terminated unexpectedly
stdout:
Invalid result type, int expected.
I know this test has been solved here before I just wonder what exactly their tests mean and why my solution fails on them.
Here is my solution PHP code:
function solution($A) {
$noe = count($A);
if($noe == 0)
return 1;
for($i=1;$i<=$noe;$i++)
{
if(!in_array($i,$A,TRUE))
return $i;
}
}
Your solution doesn't return any result, when the last element is missing. For example with array [1] correct result is 2, but your function doesn't return anything.
Another example: with array [1, 2] your solution doesn't return anything, but should return 3.
I think you won't have any problems with fixing this bug. Although you will have performance problems.
This is in C#, my program gave 100% correct and 100% performance.
Array.Sort(A);
if(A.Length == 0 )
{
return 1;
}
else
{
for(int i=0;i<A.Length;i++)
{
if(A[i] != i+1)
{
return i+1;
}
}
}
return A.Length + 1;
This is my 100% php solution to PermMissingElem in codility, is very simple, just name your variables properly:
function solution($A) {
// write your code in PHP5.5
sort($A);
$index = 0;
foreach($A as $value)
{
$expected = $index+1;
if ($expected != $value) return $expected;
$index++;
}
return $index+1;
}

PHP error: method name must be a string

I have found a bug report(http://bugs.php.net/bug.php?id=24286) about this though I am not sure if it's relevant to my problem and it's very old. This is my code:
class RegExp {
function name($e){ .... }
function email($e){ .... }
function phone($e){ .... }
}
$regexp = new RegExp();
$final_keys= array("name", "email", "phone");
for($index=0; $index < count($final_keys); $index ++){
if(!$regexp->$final_keys[$index]($_POST[$final_keys[$index]])){
$invalid_uri_vars .= $final_keys[$index].",";
}
else{
$uri_vars = "&".$final_keys[$index]."=".$_POST[$final_keys[$index]];
}
}
What it does is it uses a value from an array as the name of the method to be called. In other words, I am trying to implement a function call using a variable $final_keys[$index] as its name.
*UPDATE: I tried implementing the suggestions below, nothing seems to work. Here's one of my modifications as suggested:
for($key=0; $key < count($final_keys); $key ++){
if(!$regexp->{$final_keys[$key]}($_POST[$final_keys[$key]])){
$invalid_uri_vars .= $final_keys[$key].",";
}
else{
$uri_vars = "&".$final_keys[$key]."=".$_POST[$final_keys[$key]];
}
}
I get the same error as my original code. Another method using call_user_func but I am not sure if did it right:
for($key=0; $key < count($final_keys); $key++){
if(!call_user_func(array($regexp, $final_keys[$key]), $_POST[$final_keys[$key]])){
$invalid_uri_vars .= $final_keys[$key].",";
}
else{
$uri_vars = "&".$final_keys[$key]."=".$_POST[$final_keys[$key]];
}
}
And I get this error: Warning: call_user_func(Array) [function.call-user-func]: First argument is expected to be a valid callback in /.........testreqmeta.php on line 91
I'm still not getting any errors (other than the undefined $key in the second sample) when trying the sample code, so I can't say for certain what will fix it, but here's an approach that simplifies things and gets rid of the array indexing operation: use a foreach loop rather than a for loop.
$query = array();
foreach ($final_keys as $key) {
if(!$regexp->$key($_POST[$key])) {
$invalid_uri_vars[] = $key;
} else {
$query[] = "$key={$_POST[$key]}";
}
}
$uri_vars = implode('&', $query);
I've also replaced the repeated string appends with an array implosion, which should be slightly more performant. It also makes it easier to further process the query string, if necessary, before submitting it. There are better approaches yet, but that's a whole other topic.
NB. RegExp isn't a very good description of what the class does, hence it isn't a very good name. The class may use regular expressions, but it isn't itself a regular expression (which support operations such as "match" and "replace"; RegExp's API has none of these).
Quoting from your link:
ok, here is some workaround on this problem:
in case of
<?
class Test {
var $var = Array('test_function');
function test_function($echo_var) {
echo $echo_var;
}
}
$test_obj = new test;
$test_obj->var[0]('bla');
?>
you can avoid Fatal error in last string using this instead:
<?
$test_obj->{$test_obj->var[0]}('bla');
?>
So then:
if($regexp->{$final_keys[$index]}($_POST[$final_keys[$index]])){
There's a function for what you are trying to achieve call_user_func:
http://de2.php.net/manual/en/function.call-user-func.php

Categories