Trying to code better php - agaisn't DRY - a split string usage doubt

Assuming that:

We should always have a $street.
The $street cannot be greater then 150. Ever.
If the $street is greater then 50 it should be split into chunks of 50.
For each chunk of 50 we do have an XML element to fill in.

I have come up with something like this:


$street = $contactoVo->getRua();

$parts = '';

if(strlen($street) > 50)
{
   $parts = str_split($street, 50);
   if (empty($parts[2]))
   {
    $xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[1] = $parts[1];
   }
   elseif (!empty($parts[2]))
   {
     $xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[1] = $parts[1];
     $xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[2] = $parts[2];
     }
   }
   else
   {
     $xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[0] = $parts[0];
   }

It can be a LOT better isn’t it? :nono:

Yup. as $value gives only the values, as $key=>$value gives both the key and the value.


$a=array(
 'test'=>'hello',
 'bye'
);
foreach($a as $value)
{
  echo $value.' ';
} // echoes 'hello bye';
foreach($a as $key=>$value)
{
  echo $key.':';
  echo $value.' ';
} // echoes test:hello 0:bye

PS. See what I did there with omitting a key for the value ‘bye’ ? :wink:

I will study your post with this…
http://pt2.php.net/manual/en/control-structures.foreach.php

And reply later on that omission. :slight_smile:

Just as a word of caution, str_split will still cut the string at desired length even if it is in the middle of a word.

If you use word_wrap, you can avoid this.

Other than that, it look s like you’re making excellent progress Marcio, with ScallioXTX’s assistance.

Very nice to see. :smiley:

Almost.

When we have:

foreach($arrThings as $thing) 

we are telling, for each “key-value line” of that array, consider the value part and pass it into $thing.

foreach($arrThings as $thingKey=>thingValue) 

We are telling, for each "key-value line of that array, consider the key and the value part, and pass each as key and values into another array?

If that is so, we do have some kind of rule telling foreach to either only grab the “value”, or grab the “key and value” depending on what is after the “as” keyword?

uau… (:

I knew a foreach should be of some use here… I was seeing that $part will be an array with 0, 1, 2 index, and or simpleXML iteration lines will also have 0,1,2 index as well… and I was like: “How can I connect those two?”…

Niicee…

I’m learning…

@AnthonySterling:
I do believe that addLine will be a method that will simplify this:
$xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[1] = $part;

So that, instead of having a bunch of lines like this, we can simple have:

$address->fillLine($line);

If we need to add a city, then it will be:

$city->fillLine($line);

etc…

I do have several classes on this project… but I’m assuming that we can build even more, and work with them. And once we do that, we are actually embracing OOP. Right now, I’m on oop only perhaps. ehehe

I will try to remember this.

For now however, I will make use of a better code excerpts and, little by little, move on to better structures.

I will take ScallioXTX simplification for now.

Thank you both!! :slight_smile:

UPDATE
Ahh… but @ScallioXTX if we use:

$parts=str_split($street, 50);

        foreach($parts as $part)
        {
            $xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[1] = $part;
        } 

We always have street[1] to be filled. And the thing is, for each part, put it on street[0], then on street[1], and lastly on street[2], maybe a for with an index?

Something like this perhaps?


//split only if $street is great then 50;
if(strlen($street) > 50)
{
   $parts=str_split($street, 50);
   for($i=0; $i<3;$i++)
   {
      $xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[$i] = $parts[$i]; 
   }
}

Wrong. What if the street if less then 50 chars long. Nothing happen…
hhmmm…

So this instead perhaps… ?


if(strlen($street) > 50)
{
   $parts=str_split($street, 50);
   for($i=0; $i<3;$i++)
   {   $xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[$i] = $parts[$i];
    }
}
else
{
$xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[0] = $street;
}

:shifty:

No, I don’t see why you would :stuck_out_tongue:

Yep

No it’s just a simple array, not nested in any way.

It doesn’t know that, it just works with the given keys.
str_split returns an array without setting any of the array keys. In such arrays the keys are automatically numeric.

Put differently: an array always has numeric keys, unless you explicitly define it differently, in which case it automatically is an associative array.

Does that make sense?

Can I cry already??!!

Ok…
By doing:

foreach($parts as $idx => $part)

We are telling that, for each key on our $parts array, take them as key=>value pars ?

Is this an array inside an array?

How does it know that $idx is a numeric key ?

Ok. Because according to php manual (just seen) for str_split we do have:

If the split_length length exceeds the length of string, the entire string is returned as the first (and only) array element.

So if string is less then 50 we will have $part[0] filled with that.

Nope, that assumes there are always three parts, which isn’t necessarily true.
It’s actually quite simple:


$parts=str_split($street, 50);
foreach($parts as $idx => $part)
{
   $xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[$idx] = $part; 
}

:slight_smile:

PS. There is no need for the if (strlen($street) > 50); the code works perfectly fine without it :slight_smile:

You mean like this:


$parts=str_split($street, 50);
foreach($parts as $part)
{
  $xmlObj->command->create->children(self::OBJ_URI_CONTACT)->create->postalInfo->addr->street[1] = $part;
}

?


<?php
foreach(explode('__BREAK__', wordwrap($string, 50, '__BREAK__')) as $line){
  $address->addLine($line);
}
?>

Error:
Instead of:

$a = $key=$value; 

we should read:

$a AS $key=$value;

Those were the terms I wanted to compare as been the same.

Saved. This is for machine consumption only. No worries there. :slight_smile:

One day!!! oh!!! One day!!! I will amuse myself as well by seeing a newbie struggle! ;p

Yup. Almost. :slight_smile:

The “Almost part”:
I mean, if we have like a exam question telling us:
What type of array is this?
What should we reply? Associative? Numeric? Mixed?
Curious. (as always :s)

The “yup” part:
Even if we have not explicitly defined a key on our array second element, when we ask for that key to be echoed, we have a numeric index key returned. 0.

The “almost part (again)”:
One thing that I still miss:
When we have:
$key=>$value on the foreach, are we representing an array?

A) I mean, are those synonymous:

$a = $key=$value;

and

$a=array(); 

?

If we quote the php manual, we see:

The second form - [foreach (array_expression as $key => $value)] - does the same thing, except that the current element’s key will be assigned to the variable $key on each loop.

So it seems that we are assigning the element’s key to a variable (not necessarily an array?), and that variable will be associated => with a $value of $a on that $key.

So, I’m doubting about A).

:confused:

$key is never an array, $value might be an array in case you’re looping over a multi-dimensional array


$a = array(
  array(1,2),
  array(3,4),
);
foreach($a as $k=>$v)
{
  // first loop: $k=0, $v=array(1,2);
  // second loop: $k=1, $v=array(3,4);
}

I guess you could say that yes, since the $key is associated with the $value :slight_smile:

Which language is that, and does it do the same as php foreach($a as $key=>$value) ?

I meant

$a as $key=>$value

.

Anyway:
$key and $value are two different variables, associated, but they are NOT an array.

Is this correct?

What does the => mean? It’s something that “associates” ?

ps-
Strangely or not I better understand this syntax on another programming language:

foreach($key => $value in $a)

I believe I have no more doubts for now. :smiley:
Many new informations today! :slight_smile: Thanks a lot ScallioXTX :wink:

What? :shifty:

Precious! Thanks!

[QUOTE=rpkamp;4688765]
Which language is that, and does it do the same as php foreach($a as $key=>$value) ?

Any. :blush: That was a representation made by someone else of the following C# sintax so I believe:

foreach(KeyValuePair<type1, type2> kv in a)

But now that I think more about this, I’m not sure if in makes more sense then as.
:slight_smile: