skip to Main Content

I have a form in which the user can enter a string into a textarea. This string will then be used as a query argument in an api call to an external service.

The service has a limit for the lenght of this specific argument; it cannot exceed 512 characters and needs to be URL encoded.

While I can set the max length for the textarea to 512 this will still result in that the query argument when encoded will exceed the maximum length since any space will be encoded as %20 and so on.

Currently I am doing the following:

// 512 character long search text given by user.
$dummySearchString = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque tincidunt, nunc a consequat luctus, eros leo interdum nisl, vel convallis felis sapien eu nisl. Fusce ut viverra libero. Mauris non nulla sed elit varius volutpat. Sed in malesuada lacus. Nullam vel odio sagittis, ullamcorper mauris vel, scelerisque odio. Aliquam erat volutpat. Sed ut facilisis sapien, a rutrum sapien. Proin nec urna at ante egestas luctus sed in eros. Fusce accumsan odio sed ornare posuere. Ut consectetur arcu sed bibendum pretium. Integer tristique orci eget velit dictum, eu tristique justo aliquet. Praesent finibus egestas enim, vulputate varius tortor consequat id.';

// Encode the string, we first trim of any blank spaces from start and end.
$encodedQueryString = rawurlencode(trim($dummySearchString));

// Check the length and trim if exceeding 512 characters.
$encodedQueryString = substr($encodedString, 0, 512);

// Make http request.
$response = $this->client->request('GET', 'https://example.com/api/v1/search', [
  'query' => [
    'q' => rawurldecode($encodedQueryString),
  ],
]);

The above works most of the time but there could still be issues with trimming in the middle of an entity and so on.

What would be the best solution to make sure that the text entered in the textarea will be viable to use as a query argument in this case?

2

Answers


  1. One possibility is to encode the string character by character until the limit is reached and don’t add an encoded character if it would be cut off.

    However this can be tricky, if the string contains multi-byte characters. PHP isn’t quite my strength, but I believe the correct way to correctly get multi-byte characters is to use mb_substr.

    Login or Signup to reply.
  2. You can continuously check the length if the encoded string and then enable/disable the submission of the form accordingly. Below is a quick and dirty implementation:

    const txt = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque tincidunt, nunc a consequat luctus, eros leo interdum nisl, vel convallis felis sapien eu nisl. Fusce ut viverra libero. Mauris non nulla sed elit varius volutpat. Sed in malesuada lacus. Nullam vel odio sagittis, ullamcorper mauris vel, scelerisque odio. Aliquam erat volutpat. Sed ut facilisis sapien, a rutrum sapien. Proin nec urna at ante egestas luctus sed in eros. Fusce accumsan odio sed ornare posuere. Ut consectetur arcu sed bibendum pretium. Integer tristique orci eget velit dictum, eu tristique justo aliquet. Praesent finibus egestas enim, vulputate varius tortor consequat id.';
    
    const [query,free,submit]=["query","free","submit"].map(id=>document.getElementById(id));
    query.value=txt.slice(0,385);
    query.addEventListener("input",ev=>{
      let n=512-encodeURIComponent(query.value.trim()).length;
      submit.disabled=n<0?true:false;
      free.textContent=n>=0?`Enter up to ${n} more`:`String too long - delete ${-n}`
    })
    query.dispatchEvent(new Event("input"));
    <form>
    <textarea id="query" cols="60" rows="6"></textarea><br>
    <span id="free"></span> character(s).<br>
    <button id="submit">submit</button>
    </form>

    You will probably also need to prevent the form submission by pressing the enter key …
    (but, as already mentioned, this is just a "quick and dirty" implementation for demo purposes).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search