Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue when creating array from text string #57

Open
liataun opened this issue May 12, 2019 · 5 comments

Comments

Projects
None yet
2 participants
@liataun
Copy link

commented May 12, 2019

I am attempting to store a multi-line string in a field to store in a table I am calling Posts.

The struggle I am having is that while I can get newline characters into the stored string as \n, I seem unable to get them rendered while still using sanitation. I attempted what was described here: Stack Overflow - blade and newlines. That did not seem to work.

My next attempt was to try to pull my content field and explode on the \n character in my controller list() function:

        $posts = Post::where('publish', '=', true)->get();
        $splitPosts = collect([]);

        foreach ($posts as $post) {
//            dd($post['content']);

            $splitPosts->push([
                $post['id'] => explode('\\n', $post['content'])
                ]);
        }

        return view('posts.list')->with(['posts' => $posts, 'text' => $splitPosts]);

This almost works. The result gets stored and can be displayed in what looks like an array toString output using this display code:

                <li class='list-group-item'>
                    <pre>{!! nl2br(e($post->id)) !!}</pre>
                    <p>{{$text}}</p>
                    <p>{{ $post->content }}</p>
                    @foreach($text as $item)
                        Anything
                    @endforeach
                </li>
            @endforeach

With the resulting in the browser string output from {{$text}} being:

[{"1":["Welcome to the site! I am happy to have you reading and viewing my work."]},{"2":["Hello world! Join us","in becoming our best selves."]}]

Note that the element with id 2 has two strings and no \n remaining.

Yet when I try to access the individual lines by using {{ $text[$post->id] }} or @foreach, I get a server error ErrorException (E_ERROR) htmlspecialchars() expects parameter 1 to be string, array given (View: C:\xampp\htdocs\p4\resources\views\posts\list.blade.php).

I expect this is something to do with how I am building the array of values, but the PHP style of using arrays still gets me a bit confused.

My repository is: Project 4. I forget exactly which version of the above troubleshooting is committed there currently, but the relevant parts can easily be replaced with what I indicate above..

@liataun

This comment has been minimized.

Copy link
Author

commented May 13, 2019

Seems to be working now with many hours of trial and (server) errors.

In controller:

        $posts = Post::where('publish', '=', true)->get();

        $collection = collect([]);
        foreach($posts as $post) {
            $collection->put($post->id, explode('\\n', $post['content']));
        }

        return view('posts.list')->with([
            'posts' => $posts,
            'text' => $collection,
        ]);

Then in view:

            @foreach($posts as $post)
                    @foreach($text[$post->id] as $item)
                            <p>{{ $item }}</p>
                    @endforeach
            @endforeach

Which, at least locally from seeds, is allowing me a split on \n into dynamically created paragraphs.

Now to catch up on building out the forms, so that people can interact with all the work I put in setting up these database seeding and parsing details.

@liataun liataun closed this May 13, 2019

@liataun

This comment has been minimized.

Copy link
Author

commented May 13, 2019

Wait, nope... only works for Seeded \n.

When capturing textarea as the input type, the newly inserted field now as \r\n except that unlike the seeded values, it renders with the pre tag, but does not split with what I set for explode().

I must be missing something about how the newline characters are stored in the database. I thought I tried every character point for newlines with seeding, but none of them render the same way as those captured through the form.

How do I seed newline characters (or search field values for them) the same way as it is captured in textarea input?

@liataun liataun reopened this May 13, 2019

@susanBuck

This comment has been minimized.

Copy link
Owner

commented May 13, 2019

Hi @liataun -

I tried the solution in the StackOverflow post you linked:

{!! nl2br(e($post->content)) !!}

This worked, with the addition of a small modification to your seeder.

In your seeder, change this line:

$post2->content = 'Hello world! Join us\\nin becoming our best selves.';

To this:

$post2->content = "Hello world! Join us\nin becoming our best selves.";

What changed:

  • Used double instead of single quotes
  • Removed double backslash

Explanation:

Escape sequences are funny when making strings with single quotes - the backslashes get interpreted as literal backslashes, even when you use a double backsplash.

Because of this, it's best to use double quotes when working with escape sequences like \n.

More details here: PHP: Strings single quoted

@liataun

This comment has been minimized.

Copy link
Author

commented May 13, 2019

That works! Thank you, @susanBuck. I tried all sorts of variations of single and double backslash, unicode representations for the characters, etc., but would probably never have remembered to try double quotes. I started doing single quotes for PHP and HTML at the start of the class, and have been trying to stay consistent!

Will there be a problem style guides wise, if I have the one area where I use double quote string literals and single quote most other places? Or should I do a project wide search-replace?

@susanBuck

This comment has been minimized.

Copy link
Owner

commented May 14, 2019

As a single-quote user as well, it's one of those gotchas I often forget about!

No need to do a project search/replace. I think it's reasonable to be inconsistent in this instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.