Complete email addresses in a flat array using static domains (only where missing), then implode

122 views Asked by At

I have written a script (I'm quite new to PHP) which will take a list of elements as an input and checks whether it’s only a username or it contains username+domain name (I mean email).

If it’s only a username, then it will append '@test.com' into that username and combine all the strings together to send an email notification.

$recipients = array("kumar", "[email protected]", "ravi", "[email protected]");

$with_domain = array();
$without_domain = array();

$exp = "/^\S+@\S+\.\S+$/";
foreach ($recipients as $user) {
    if(preg_match($exp, $user)) {
        array_push($with_domain, $user);
    } else {
        array_push($without_domain, $user);
    }
}

$without_domain_new = implode("@test.com", $without_domain)."@test.com";

print_r($with_domain);
print_r($without_domain_new);
echo "<br>";

$r = implode("", $with_domain);
$s = $without_domain_new.$r;

print "Email notification need to be sent to: $s";

Here script works as expected. But is the line $r = implode("", $with_domain); $s = $without_domain_new.$r; really required?

Is it be possible to merge array and strings in PHP? I mean, is it possible to merge $with_domain and $without_domain_new and store it to $s as a string?

5

There are 5 answers

0
Cositanto On

Use:

$emails = array_map(function ($username) {
    return preg_match("/^\S+@\S+\.\S+$/", $username) ? $username : $username . '@test.com';
}, $recipients);

It will give you an array with all email addresses you want.

And then you can use implode('', $emails) or maybe implode(',', $emails) to convert an array to a string for sending notification.

2
Lennard K On

If you want to merge the arrays and strings into a single string, you can use the implode() function to convert the arrays to strings and then concatenate them together. Here's an updated version of your code:

<?php
$recipients = array("kumar", "[email protected]", "ravi", "[email protected]");

$with_domain = array();
$without_domain = array();

$exp = "/^\S+@\S+\.\S+$/";
foreach ($recipients as $user) {
    if (preg_match($exp, $user)) {
        array_push($with_domain, $user);
    } else {
        array_push($without_domain, $user);
    }
}

$without_domain_new = implode("@test.com ", $without_domain) . "@test.com";
$combined = implode(", ", array_merge($with_domain, [$without_domain_new]));

print "Email notification needs to be sent to: $combined";
?>

In this updated code, $without_domain_new is created by using implode() to concatenate the elements of the $without_domain array with the string "@test.com " (note the space after .com) as the delimiter. Then, the $with_domain array and $without_domain_new are merged using array_merge() to combine them into a single array. Finally, the merged array is imploded with ", " (comma followed by a space) as the delimiter to create the desired string, which is stored in $combined.

Now, when you print $combined, it will display the merged string containing all the email addresses with and without domains, separated by commas and spaces.

0
RockstarRen On

Firstly, I'd suggest since you're starting out, try simplifying the code a bit. Example: array() is not necessary. Rather just use []. I also prefer single quotes, but that's just me :) So your array:

$recipients = array("kumar", "[email protected]", "ravi", "[email protected]");

Becomes:

$recipients = ['kumar', '[email protected]', 'ravi', '[email protected]'];

Also array_push is usually used when multiple array items are needing to be pushed towards and array, so a simple $array[] = 'something'; will suffice here.

Now onto the actual issue at hand.

You can simplify what you're trying to achieve with this:

$recipients = ['kumar', '[email protected]', 'ravi', '[email protected]'];
$users = [];

foreach ($recipients as $user) {
    if (preg_match("/^\S+@\S+\.\S+$/", $user)) {
        $users[] = $user;
    } else {
        $users[] = $user . '@test.com';
    }
}

print 'Email notification need to be sent to: ' . implode(', ', $users);

That way, you're adding all the users to the $users array and appending @test.com to the ones who need appending. Dealing with one array, since you're interested in one result, i.e., users needing to be emailed :)

0
The fourth bird On

You don't have to create multiple arrays to store the intermediate results and do multiple implode's to get the final result. You can map your array with strings so that they all have the right format, and then implode only once.

When using implode with an empty string (which is the default), your result will have all strings concatenated without a delimiter and you can not tell the email addresses apart.

If your email addresses can contain only a single @ char, you can update the pattern using a negated character class to exclude matching an @ char

$recipients = ["kumar","[email protected]","ravi","[email protected]"];
$pattern = "/^[^\s@]+@[^\s@]+\.[^\s@]+$/";
$s = implode(
    ", ",
    array_map(fn($user) => preg_match($pattern, $user) ? $user : $user . "@test.com", $recipients)
);

echo $s;

Output

[email protected], [email protected], [email protected], [email protected]

See a PHP demo.

0
mickmackusa On

It seems simplest to me that you just use preg_replace() to add an email domain to any string that doesn't have it, then join the results with a comma and a space.

Code: (Demo)

$recipients = [
    "kumar",
    "[email protected]",
    "ravi",
    "[email protected]"
];

echo implode(
         ', ',
         preg_replace(
             '/^[^@]+$/',
             '[email protected]',
             $recipients
         )
     );

Result:

[email protected], [email protected], [email protected], [email protected]