473,385 Members | 1,877 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

array_walk - userdata as array by ref

here's a quirk i can't seem to handle, just hack. since call-time
by-reference is depreciated and i don't want to enable it in the php.ini,
i'm kind of stuck when i want to pass userdata as an array byref that is
initially = array().

// the array being walked
$numbers = array(1, 56, 999, 1000, 28, 65);

// the work-around

// the callback
function validateInput(&$value, $key, &$errors)
{
$maxValue = 999;
if ($value <= $maxValue) return;
$errors[1][$key] = 'Element ' . $key. ' must be a whole number between 0
and ' . $maxValue . '.';
}
// the hack
$error = array();
$errors = array('', &$error);
array_walk($numbers, 'validateInput', $errors);
$errors = $errors[1];
print_r($errors);

// what i'd like to do

// the callback
function validateInput(&$value, $key, &$errors)
{
$maxValue = 999;
if ($value <= $maxValue) return;
$errors[$key] = 'Element ' . $key. ' must be a whole number between 0 and
' . $maxValue . '.';
}
$errors = array();
array_walk($numbers, 'validateInput', $errors);
print_r($errors);
it seems as though php doesn't allocate memory for $errors when it is
defined as an empty array since it has no data (!isset), and therefore
there's a pointer to nothing (figuratively). i assume since $errors =
array('', &$error) allocates memory for the structure, the callback then has
something to work on. the '' being what actually triggers allocation (makes
room for \0 i guess). that was my reasoning when i came up with the hack,
but i'd like to know for sure.

does that sound about right? suggestions on getting the results i looking
for?

tia,

me

Apr 20 '07 #1
12 2924
Steve wrote:
here's a quirk i can't seem to handle, just hack. since call-time
by-reference is depreciated and i don't want to enable it in the php.ini,
i'm kind of stuck when i want to pass userdata as an array byref that is
initially = array().

// the array being walked
$numbers = array(1, 56, 999, 1000, 28, 65);

// the work-around

// the callback
function validateInput(&$value, $key, &$errors)
{
$maxValue = 999;
if ($value <= $maxValue) return;
$errors[1][$key] = 'Element ' . $key. ' must be a whole number between 0
and ' . $maxValue . '.';
}
// the hack
$error = array();
$errors = array('', &$error);
array_walk($numbers, 'validateInput', $errors);
$errors = $errors[1];
print_r($errors);

// what i'd like to do

// the callback
function validateInput(&$value, $key, &$errors)
{
$maxValue = 999;
if ($value <= $maxValue) return;
$errors[$key] = 'Element ' . $key. ' must be a whole number between 0 and
' . $maxValue . '.';
}
$errors = array();
array_walk($numbers, 'validateInput', $errors);
print_r($errors);
it seems as though php doesn't allocate memory for $errors when it is
defined as an empty array since it has no data (!isset), and therefore
there's a pointer to nothing (figuratively). i assume since $errors =
array('', &$error) allocates memory for the structure, the callback then has
something to work on. the '' being what actually triggers allocation (makes
room for \0 i guess). that was my reasoning when i came up with the hack,
but i'd like to know for sure.

does that sound about right? suggestions on getting the results i looking
for?

tia,

me
Both of the code you posted did not work on my box (php5.2) unmodified.

My initial thought will be using foreach on the array $numbers, but you
might have your own reason not to use it.
Hendri Kurniawan
Apr 20 '07 #2
| Both of the code you posted did not work on my box (php5.2) unmodified.
|
| My initial thought will be using foreach on the array $numbers, but you
| might have your own reason not to use it.

i usually do. however, i'm prototyping something. here's what gives me the
results...in case my free-handed post is why it doesn't work on your box.
thanks for looking at it. sorry for the text-wrapping here...if you just
backspace the wrap, it should be very easy to read/follow.

<?
$inputs['Personnel'] = array(
'bodyTech' =0 ,
'bodyTechAppr' =0 ,
'paintTech' =0 ,
'paintTechAppr' =0 ,
'paintPreps' =0 ,
'mechanicTechs' =0 ,
'estimators' =0 ,
'otherEmployees' =0
);
$inputs['Facility'] = array(
'bodyShopLocation' ='' ,
'franchises' ='' ,
'totalSqFeet' =0 ,
'productionSqFeet' =0 ,
'totalWorkStations' =0 ,
'totalPaintBooths' =0 ,
'totalDetailStalls' =0
);
function retrieveInput(&$value, $key, $source)
{
$default = 0;
if ($key == 'bodyShopLocation'){ $default = ''; }
if ($key == 'franchises'){ $default = ''; }
$value = isset($source[$key]) ? $source[$key] : $default;
}
function validateInput(&$value, $key, &$errors)
{
$inputName = '';
$maxValue = 999;
switch ($key)
{
case 'bodyShopLocation' : if (in_array($value, array('', 'ON SITE',
'OFF SITE'))){ return; }
$errors[$key] = 'BODY SHOP LOCATION must be
either on-site or off-site.';
return;
break;
case 'franchises' : if (in_array($value, array('', 'SINGLE',
'MULTIPLE'))){ return; }
$errors[$key] = 'FRANCHISE TYPE must be
either single or multiple.';
return;
break;
case 'bodyTech' : $inputName = 'BODY TECHNICIANS';
break;
case 'bodyTechAppr' : $inputName = 'BODY TECHNICIAN APPRENTICES';
break;
case 'paintTech' : $inputName = 'PAINT TECHNICIANS';
break;
case 'paintTechAppr' : $inputName = 'PAINT TECHNICIAN APPRENTICES';
break;
case 'paintPreps' : $inputName = 'PAINT PREPS';
break;
case 'mechanicTechs' : $inputName = 'MECHANICAL TECHNICIANS';
break;
case 'estimators' : $inputName = 'ESTIMATORS';
break;
case 'otherEmployees' : $inputName = 'OTHER EMPLOYEES';
break;
case 'totalSqFeet' : $inputName = 'TOTAL SQUARE FEET';
$maxValue = 9999999; break;
case 'productionSqFeet' : $inputName = 'PRODUCTION AREA SQUARE FEET';
$maxValue = 9999999; break;
case 'totalWorkStations' : $inputName = 'TOTAL WORK STATIONS';
break;
case 'totalPaintBooths' : $inputName = 'TOTAL PAINT BOOTHS';
break;
case 'totalDetailStalls' : $inputName = 'TOTAL DETAIL STALLS';
break;
default : return; break;
}
if ($value <= $maxValue) return;
$errors[1][$key] = $inputName . ' must be a whole number between 0 and ' .
$maxValue . '.';
}
array_walk($inputs['Personnel'], 'retrieveInput', $_REQUEST);
array_walk($inputs['Facility'], 'retrieveInput', $_REQUEST);
$error = array();
$errors = array('', &$error);
array_walk($inputs['Personnel'], 'validateInput', $errors);
array_walk($inputs['Facility'], 'validateInput', $errors);
$errors = count($errors) 1 ? $errors[1] : array();
echo '<pre>' . print_r($inputs, true) . '</pre>';
echo '<pre>' . print_r($errors, true) . '</pre>';
?>
Apr 20 '07 #3
Steve wrote:
| Both of the code you posted did not work on my box (php5.2) unmodified.
|
| My initial thought will be using foreach on the array $numbers, but you
| might have your own reason not to use it.

i usually do. however, i'm prototyping something. here's what gives me the
results...in case my free-handed post is why it doesn't work on your box.
thanks for looking at it. sorry for the text-wrapping here...if you just
backspace the wrap, it should be very easy to read/follow.
<SNIPPED CODE>

Umm.. again sorry if this is not the answer you are looking for.
This is what i came up with (see bottom of page)

What it basically does is that it replaces the array_walk to normal
function. Inside the function, instead of returning after correctly
validating the input, I've put "continue".

At the end i returned the errors array.
Hendri Kurniawan

<?
$inputs['Personnel'] = array(
'bodyTech' =0 ,
'bodyTechAppr' =0 ,
'paintTech' =0 ,
'paintTechAppr' =0 ,
'paintPreps' =0 ,
'mechanicTechs' =0 ,
'estimators' =0 ,
'otherEmployees' =0
);
$inputs['Facility'] = array(
'bodyShopLocation' ='' ,
'franchises' ='' ,
'totalSqFeet' =0 ,
'productionSqFeet' =0 ,
'totalWorkStations' =0 ,
'totalPaintBooths' =0 ,
'totalDetailStalls' =0
);
function retrieveInput(&$value, $key, $source)
{
$default = 0;
if ($key == 'bodyShopLocation'){ $default = ''; }
if ($key == 'franchises'){ $default = ''; }
$value = isset($source[$key]) ? $source[$key] : $default;
}
function validateInput($value)
{
$inputName = '';
$maxValue = 999;
$errors = array();
foreach($value as $key=>$value) {
switch ($key)
{
case 'bodyShopLocation' :
if (in_array($value, array('', 'ON SITE', 'OFF SITE'))){ continue; }
$errors[$key] = 'BODY SHOP LOCATION must be either on-site or
off-site.';
continue;
break;
case 'franchises' :
if (in_array($value, array('', 'SINGLE', 'MULTIPLE'))){ continue; }
$errors[$key] = 'FRANCHISE TYPE must be either single or multiple.';
continue;
break;
case 'bodyTech' : $inputName = 'BODY TECHNICIANS';
break;
case 'bodyTechAppr' : $inputName = 'BODY TECHNICIAN APPRENTICES';
break;
case 'paintTech' : $inputName = 'PAINT TECHNICIANS';
break;
case 'paintTechAppr' : $inputName = 'PAINT TECHNICIAN APPRENTICES';
break;
case 'paintPreps' : $inputName = 'PAINT PREPS';
break;
case 'mechanicTechs' : $inputName = 'MECHANICAL TECHNICIANS';
break;
case 'estimators' : $inputName = 'ESTIMATORS';
break;
case 'otherEmployees' : $inputName = 'OTHER EMPLOYEES';
break;
case 'totalSqFeet' : $inputName = 'TOTAL SQUARE FEET';
$maxValue = 9999999; break;
case 'productionSqFeet' : $inputName = 'PRODUCTION AREA SQUARE FEET';
$maxValue = 9999999; break;
case 'totalWorkStations' : $inputName = 'TOTAL WORK STATIONS';
break;
case 'totalPaintBooths' : $inputName = 'TOTAL PAINT BOOTHS';
break;
case 'totalDetailStalls' : $inputName = 'TOTAL DETAIL STALLS';
break;
default : continue; break;
}
if ($value <= $maxValue) continue;
$errors[$key] = $inputName . ' must be a whole number between 0 and ' .
$maxValue . '.';
}

return $errors;
}

array_walk($inputs['Personnel'], 'retrieveInput', $_REQUEST);
array_walk($inputs['Facility'], 'retrieveInput', $_REQUEST);
$errors = array();
$errors = array_merge($errors,validateInput($inputs['Personnel']));
$errors = array_merge($errors,validateInput($inputs['Facility']));
echo '<pre>' . print_r($inputs, true) . '</pre>';
echo '<pre>' . print_r($errors, true) . '</pre>';
?>
Apr 20 '07 #4

"Hendri Kurniawan" <as****@email.comwrote in message
news:13*************@corp.supernews.com...

thanks hendri. btw, i didn't know you could do:

foreach($value as $key=>$value)

and expect to have the first $value preserved. i suppose though, thinking
about it, php gets a single reference to the $value array and then works off
the stack at that address. the second $value should be a new copy of the
element at $key - the next loop still working from the old stack and not the
new value of $value.

it's not so much that i want an alternative, it's that i want to understand
exactly why the hack works yet the straight-forward approach does not - even
though the docs say it should. i'm just using array_walk to benchmark
data-retrieval in a custom db class...rather than using a foreach on the
records returned, i'd be trying to walk the records - goal being to
standardize access methods, i.e. $records[0]['FOO'] as the structure...a row
and field as keys. the foreach is pretty fast over 200K rows...just wanna
see how much faster the native iteration is over the native enumeration. :)
i'm just wierd like that.

anyway, the code i posted here was me just playing with array_walk in a
practical scenario. just trying to find out about what all i could do with
the userdata param. that's when i ran into this bit of undefined behavior.
and, isn't it wonderful that it is undefined yet a single character's
correction would fix the problem - that character being '&' as a call-time
by-reference.

thanks for the help.
Apr 20 '07 #5
Steve wrote:
| Both of the code you posted did not work on my box (php5.2) unmodified.
|
| My initial thought will be using foreach on the array $numbers, but you
| might have your own reason not to use it.

i usually do. however, i'm prototyping something. here's what gives me the
results...in case my free-handed post is why it doesn't work on your box.
thanks for looking at it. sorry for the text-wrapping here...if you just
backspace the wrap, it should be very easy to read/follow.

Also forgot to mention that posted code also doesn't work.
(You might have found a bug?? :D )

Hendri Kurniawan
Apr 20 '07 #6
Steve wrote:
"Hendri Kurniawan" <as****@email.comwrote in message
news:13*************@corp.supernews.com...

thanks hendri. btw, i didn't know you could do:

foreach($value as $key=>$value)

and expect to have the first $value preserved. i suppose though, thinking
about it, php gets a single reference to the $value array and then works off
the stack at that address. the second $value should be a new copy of the
element at $key - the next loop still working from the old stack and not the
new value of $value.

it's not so much that i want an alternative, it's that i want to understand
exactly why the hack works yet the straight-forward approach does not - even
though the docs say it should. i'm just using array_walk to benchmark
data-retrieval in a custom db class...rather than using a foreach on the
records returned, i'd be trying to walk the records - goal being to
standardize access methods, i.e. $records[0]['FOO'] as the structure...a row
and field as keys. the foreach is pretty fast over 200K rows...just wanna
see how much faster the native iteration is over the native enumeration. :)
i'm just wierd like that.

anyway, the code i posted here was me just playing with array_walk in a
practical scenario. just trying to find out about what all i could do with
the userdata param. that's when i ran into this bit of undefined behavior.
and, isn't it wonderful that it is undefined yet a single character's
correction would fix the problem - that character being '&' as a call-time
by-reference.

thanks for the help.


Yeah, glad to help.. It also challenges my mind not to be complacent.

Hendri
Apr 20 '07 #7
| Also forgot to mention that posted code also doesn't work.
| (You might have found a bug?? :D )

well, if it is consistent then it's a 'feature', right? lol.

btw, i ran it on php 5.1.6.
Apr 20 '07 #8
On 20.04.2007 05:57 Steve wrote:
here's a quirk i can't seem to handle, just hack. since call-time
by-reference is depreciated and i don't want to enable it in the php.ini,
i'm kind of stuck when i want to pass userdata as an array byref that is
initially = array().

// the array being walked
$numbers = array(1, 56, 999, 1000, 28, 65);

// the work-around

// the callback
function validateInput(&$value, $key, &$errors)
{
$maxValue = 999;
if ($value <= $maxValue) return;
$errors[1][$key] = 'Element ' . $key. ' must be a whole number between 0
and ' . $maxValue . '.';
}
// the hack
$error = array();
$errors = array('', &$error);
array_walk($numbers, 'validateInput', $errors);
$errors = $errors[1];
print_r($errors);

// what i'd like to do

// the callback
function validateInput(&$value, $key, &$errors)
{
$maxValue = 999;
if ($value <= $maxValue) return;
$errors[$key] = 'Element ' . $key. ' must be a whole number between 0 and
' . $maxValue . '.';
}
$errors = array();
array_walk($numbers, 'validateInput', $errors);
print_r($errors);
it seems as though php doesn't allocate memory for $errors when it is
defined as an empty array since it has no data (!isset), and therefore
there's a pointer to nothing (figuratively). i assume since $errors =
array('', &$error) allocates memory for the structure, the callback then has
something to work on. the '' being what actually triggers allocation (makes
room for \0 i guess). that was my reasoning when i came up with the hack,
but i'd like to know for sure.

does that sound about right? suggestions on getting the results i looking
for?

tia,

me
Hi

how about

function validateInput(&$value, $key, $errs)
{
$maxValue = 999;
if ($value <= $maxValue) return;
$errs[0][$key] = "message...";
}

array_walk($numbers, 'validateInput', array(&$errors));
print_r($errors);


--
gosha bine

extended php parser ~ http://code.google.com/p/pihipi
blok ~ http://www.tagarga.com/blok
Apr 20 '07 #9
| function validateInput(&$value, $key, $errs)
| {
| $maxValue = 999;
| if ($value <= $maxValue) return;
| $errs[0][$key] = "message...";
| }
|
| array_walk($numbers, 'validateInput', array(&$errors));
| print_r($errors);

beautiful...i check it. i wonder why it has to be that way instead of just
passing $errors in?
Apr 20 '07 #10
| function validateInput(&$value, $key, $errs)
| {
| $maxValue = 999;
| if ($value <= $maxValue) return;
| $errs[0][$key] = "message...";
| }
|
| array_walk($numbers, 'validateInput', array(&$errors));
| print_r($errors);

doesn't work on my machine (php 5.1.6)
Apr 20 '07 #11
On 20.04.2007 15:20 Steve wrote:
| function validateInput(&$value, $key, $errs)
| {
| $maxValue = 999;
| if ($value <= $maxValue) return;
| $errs[0][$key] = "message...";
| }
|
| array_walk($numbers, 'validateInput', array(&$errors));
| print_r($errors);

doesn't work on my machine (php 5.1.6)

works for me in php4.3 and 5.2. Make sure you're doing everything right.
--
gosha bine

extended php parser ~ http://code.google.com/p/pihipi
blok ~ http://www.tagarga.com/blok
Apr 20 '07 #12

"gosha bine" <st********@gmail.comwrote in message
news:46**********************@read.cnntp.org...
| On 20.04.2007 15:20 Steve wrote:
| | function validateInput(&$value, $key, $errs)
| | {
| | $maxValue = 999;
| | if ($value <= $maxValue) return;
| | $errs[0][$key] = "message...";
| | }
| |
| | array_walk($numbers, 'validateInput', array(&$errors));
| | print_r($errors);
| >
| doesn't work on my machine (php 5.1.6)
| >
| >
|
| works for me in php4.3 and 5.2. Make sure you're doing everything right.

including cut/paste. :)

it must be either how php is compiled or the settings it's running. i'll
keep playing with your example and see if i can get it there. btw, i don't
expect that there would be a problem with any of this in versions less than
php 5.

cheers.
Apr 20 '07 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Phil Powell | last post by:
<?php class Grad { var $dbFormExemptionArray = array(); function Grad ($id = '') { ...
2
by: Reply-Via-Newsgroup | last post by:
Folks, I have a multi-dimensional array that I read from my mysql database. I'd like to run strip slashes against each element and I'm pretty sure that array_walk() (or array_map) is likely to...
1
by: comp.lang.php | last post by:
/** * Filter results according to given instruction * * @access private * @param object $result (reference) * @return object $filteredResult */ function &filterResults(&$result) { //...
6
by: steve | last post by:
Hi, I have never used array_walk, and quite frankly, cannot see why I should use it instead of foreach. Can someone shed some light on the cases where array_walk is the one to use, and what php...
1
by: e | last post by:
I'm using forms authentication on a site. When the user logs in via the login page, the entered creds are checked against AD, and if valid, an encrypted forms authentication ticket is produced and...
3
by: Mr.KisS | last post by:
Hello all, I'm working with : WinXP PRO SP1, MS SQL 2005 Express, Visual Web Dev 2005 Express. I have an aspx page which must execute a stored procedure : ______________ try {...
0
by: Sean Patterson | last post by:
Hey all, I've followed the examples online on how to use Forms Authentication to create a ticket, assign it a role, and then intercept it in the Global.asax file to make sure it gets sucked in...
2
by: lwoods | last post by:
I have the following function: function clean_form( &$from_check ) { if(is_array($from_check)){ array_walk(&$from_check,'clean_form'); return; } else { $value =...
0
code green
by: code green | last post by:
Using the third parameter to pass the address of a user array to array_walk fills the user array with data. But once array_walk finishes executing the user array empties. Can any body explain this?...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.