0

Here I have an input example:

Example

When user enters formate like {login}:{ip}:{password} or {ip}|{:login} any formate, PHP gets from database these datas and add them to the txt file and the user downloads it.

Here is a result should look like:

Result How to do it?

I tried this:

$text = '{login}:{password}:{ip}';
preg_match_all('/\{[^\}]*\}/', $text, $matches);
$return = str_replace($matches[0], "", $text);
$splitter = substr($return, 0,1);

But it doesn't works

ADyson
  • 57,178
  • 14
  • 51
  • 63
Ismoil
  • 11
  • 2
  • 1
    I would advise against using regex. You may find a solution that works for simple passwords, but what if the password contains a `{` or a `:` character? You'd be better off having separate form fields in the first place, which will make processing much easier – Rob Eyre May 04 '23 at 09:10
  • 1
    It is really not clear what you are asking here, or what you think this code is doing for you! – RiggsFolly May 04 '23 at 09:12
  • 2
    No-one should be able to export a password from the database. Passwords should be hashed, to begin with, and should not be made available externally through any functionality. – ADyson May 04 '23 at 09:18
  • 1
    Welcome on SO, firstly security wise that is dangerous and secondly you need to understand this is not a code writing service please read [how to ask](https://stackoverflow.com/help/how-to-ask). – Codestrip May 04 '23 at 09:21
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community May 04 '23 at 09:26
  • Why not just use CSV? – ThW May 05 '23 at 11:14
  • @ThW: I think that the point of this input field is that the user can decide which variable he wants, in any order, with some other text also. It could be `Login: {login}, IP address: {ip}` or anything else. He just wants to inject some variables into another string. But effectively, it's probably supposed to go in a log file, but that we don't know. – Patrick Janser May 07 '23 at 13:45

2 Answers2

0
if (stripos($format, "{password}") !== false ) {
    $format = str_replace('{password}', $user->password, $format);
}
if (stripos($format, "{ip}")) {
    $format = str_replace("{ip}", $user->ip, $format);
}
Ismoil
  • 11
  • 2
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 04 '23 at 09:58
0

If I understand it correctly, login, password and ip are database field names. So you could only accept valid chars for DB field names instead of [^\}]*, which might be too lax.

You could start off with /\{([a-z_]\w*)\}/gi instead.
Test it here: https://regex101.com/r/4hg0aC/1

The second step would be to validate that these field names really exist in your database table. If the DB doesn't change, then you could have two ways to achieve it:

  • A) replace the regex with /\{(login|password|ip)\}/gi and then do a strtolower() of the matched group.
  • B) Check that the match is in a defined array of field names. This array could even be the result of a SQL query to get the field names.

Then build your DB request with PDO to get the data.

If you already have a variable containing the fields you want to expose, then you could simply check that the property exists or not.

Example of PHP code:

<?php
// The regex to capture any kind of variable (with wrong syntax accepted).
$regexTemplateVar = '/\{([^}]*)\}/i';
// The regex to see if the field name is kind of valid or not.
$regexValidField = '/^[a-z_]\w*$/i';

// The input text is like a template.
$template = <<<END_OF_TEMPLATE
{login}:{password}:{ip}

What about other field names? `e-mail` would be acceptable depending on the DB but it's
probably not a good idea to create field names with special chars.

{_ipv6},{name},{non_existant_field},{1_not_ok_with_leading_numbers}
END_OF_TEMPLATE;

// For testing purpose, a demo $user variable.
$user = (object)[
    'name' => 'James Bond',
    'login' => 'james_007',
    'password' => 'should never be here, in any case!',
    'ip' => '145.56.87.42',
    '_ipv6' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
];

// Search and replace with a custom function.
$output = preg_replace_callback(
    // The search pattern.
    $regexTemplateVar,
    // The callback function with access to some global variables.
    function($match) use ($user, $regexValidField) {
        $fieldName = strtolower($match[1]);
        // Check that the field name is valid or not.
        if (preg_match($regexValidField, $fieldName)) {
            if (isset($user->$fieldName)) {
                return $user->$fieldName;
            } else {
                return "{ERROR: '$fieldName' doesn't exist!}";
            }           
        }
        else {
            return "{ERROR: '$fieldName' is not valid!}";
        }

    },
    // The input string.
    $template
);

print $output;

You can test it here: https://onlinephp.io/c/71e2d

Patrick Janser
  • 3,318
  • 1
  • 16
  • 18