Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
ModeSix
Mar 14, 2009

I'm having a hard time passing an array of values via POST. Now you might say "wow you're dumb" and maybe I am, but let me explain.

I am using jQuery on a page to add some additional rows to a table within a form that gets submitted, the number of rows needs to be dynamic and reloading the page and adding it via php isn't an option as there's some pretty heavy lifting being done on this page and it would take 5-10 seconds each time they wanted to add a new input field.

So I've worked around this by using jQuery. Why jQuery you ask? This has to run in old as balls browsers so I can't use something else.

Here is the situation so far.

When I post it will pass the value in the first row of the table, naturally this row exists within the hard coded PHP as it's the reference row.

I'm adding additional rows into the DOM using this handy little script:

code:
<script type="text/javascript">
$(document).ready(function(){
    var addButton = $('.add_button'); //Add button selector
    var x = 1; //Initial field counter is 1
    var fieldHTML = '<tr id="rw'+ x +'"><td><input type="text" name="additional_items[]" /></td><td><a href="javascript:void(0);" class="remove_button" title="Remove Field"><img src="remove-icon.png" style="width:24px;height:24px;"/></a></td></tr>'; //New input field html

    //Once add button is clicked
    $(addButton).click(function(){
        //Check maximum number of input fields
        if(x){
            x++; //Increment field counter
            $('#add_table tr:last').after(fieldHTML); //Add field html
        }
    });

    //Once remove button is clicked
    $(this).on('click', '.remove_button', function(e){
        e.preventDefault();
        $(this).parents('tr:first').remove(); //Remove field html
        x--; //Decrement field counter
    });
});
</script>
And I can inspect them in Chrome inspector and they appear properly.

Is it that a POST won't pick up these fields that are added using jQuery or are they just not formatted properly?

The hardcoded row looks like this in my html file:
code:
<tr>
                 <td><input type="text" name="additional_items[]" /></td>
                 <td style="vertical-align:middle;"><a href="javascript:void(0);" class="add_button" title="Add field"><img src="add-icon.png" style="width:24px;height:24px;" /></a></td>
</tr>
This is of course encapsulated within my <form> fields and it adds the new row directly below what you see above in the DOM.

Please, any assistance would be hugely helpful as this project is due by EOD Sunday and this is really my last blocker before I submit it for client approval.

Adbot
ADBOT LOVES YOU

ModeSix
Mar 14, 2009

Banditu posted:

Hello Mode6,

It works for me when using the code you posted.

So maybe the issue is somewhere else?





Hm. Ok interesting. How are you picking it up in the $_POST on the receiving page?

ModeSix
Mar 14, 2009

Banditu posted:

To check the value I just used print_r :

php:
<?php
      print_r($_POST['additional_items']);
?>


Awesome. I've been checking it the same way and only getting one of the values.

Something fishy going on with this.

Edit: turns out I'm just bad at html and had two opening body tags which may or may not have been causing it not to work. Removed the additional body tags and made the form tag outside the table instead of inside and now it works. Not sure which is the reason but it works.

Thanks for validating that it was a me issue not a code issue. Really helped.

ModeSix fucked around with this message at 14:47 on Jun 27, 2020

ModeSix
Mar 14, 2009

I have a very particular issue I am trying to tackle with string sorting and I've got it 80% of the way there.

Let's say I've got 5 strings as follows:

2 for 1 - 6" Apple Pies
2 for 1 - 12" Apple Pies
50% Off - Banana Cakes
50% Off - 30 Carrot Cakes
2 For 1 - Dead Thing
2 for 1 - 5 Zebra Skins

Right now I can get them to sort like this:
50% off - Banana Cakes
2 for 1 - Dead Thing
2 for 1 - 6" Apple Pies
2 for 1 - 12" Apple Pies
50% Off - 30 Carrot Cakes
2 for 1 - 5 Zebra Skins

But ideally I'd like them to be sortable in alphabetical order, then by quantity/size if there is one as shown in the top list. Taking into account that 6 is before 12 (as we all know numbering in php is a pain).

I've gotten it most of the way there using explodes, substrings etc. but I can't figure out how to merge with leading numbers, without leading numbers together to get a pure alphabetical, then size/quantity list.

If someone can point me in the right direction on thi it would be super helpful.

My spaghetti mess looks like this right now:

code:
if (mysqli_num_rows($result) != 0) {
		while ($crow = mysqli_fetch_array($result)) {
			$_excname = explode("-", $crow['PageName']);
			
			if (strlen(trim($_excname[1])) > 0) {
				$_cname = $_excname[1];
			} else {
				$_cname = $_excname[0];
			}

			$_cnum = preg_match_all('!\d+!', $_cname, $matches);

			if ($_cnum > 0) {
				$_csort = $crow['StoreName'] . ',' . str_pad(trim($_cname), 70, '0', STR_PAD_LEFT); 
			} else {
				// This puts named items before items with a quantity
				$_csort = $crow['StoreName'] . ',0,' . trim($_cname);

				// This puts items with a quantity items before items with only a name
				//$_csort = $crow['StoreName'] . ',99999,' . trim($_cname);
			}

			$_coupons[$_x][0] = $crow;
			$_coupons[$_x][1] = $_csort;
			$_x++;
		}
	}
	usort($_coupons, function ($a, $b) { // anonymous function
		// compare numbers or strings non-case-sensitive
		return strcmp(strtoupper($a[1]), strtoupper($b[1]));
	});

ModeSix
Mar 14, 2009

Does anyone have any recommendations for creating a REST API that is backed by an existing MySQL database?

I've taken a look at Lumen, but honestly I can't figuring the routing on it, even though syntactically it looks almost exactly like creating a REST API in NodeJS(Express). The documentation on Lumen is so poor I can't figure out to get it to work.

ModeSix fucked around with this message at 04:27 on Jan 7, 2021

ModeSix
Mar 14, 2009

musclecoder posted:

How robust does it need to be? Is this just a couple of endpoints? If so, any modern framework (Symfony, Laravel) will allow you to set one up very easily, provide serializers and normalizers to convert your data to/from one format to another. If it needs to be very robust, really respect HATEOS, HTTP, REST, etc then you may want to look into API Platform: https://api-platform.com/

It's going to be pretty simple, using it to generate endpoints for a mobile application that needs access to some site/user data from the main site and doing direct DB calls is a no-no for many reasons. I just need to get some responses from some joins off the database, be able to put updates and validate auth. Simple is all I need.

I'll take a look at Symfony, I think Lumen uses it in there because I was getting some good errors off of it that referenced Symfony.

ModeSix
Mar 14, 2009

rt4 posted:

You could probably use this to automate the entire thing

https://github.com/mevdschee/php-crud-api

This looks like exactly what I am looking for. Brilliant, thanks!

ModeSix
Mar 14, 2009

I am trying to find the highest value for a given combination of array keys.

The array I have is thus:

code:
Array
(
    [0] => Array
        (
            [year] => 21
            [month] => 1
            [gender] => 1
            [votes] => 2
            [user_id] => 1
            [username] => testuser123
        )

    [1] => Array
        (
            [year] => 21
            [month] => 1
            [gender] => 2
            [votes] => 13
            [user_id] => 2
            [username] => prettygirl
        )

    [2] => Array
        (
            [year] => 21
            [month] => 1
            [gender] => 2
            [votes] => 1
            [user_id] => 4
            [username] => allenalb
        )

    [3] => Array
        (
            [year] => 20
            [month] => 12
            [gender] => 1
            [votes] => 1
            [user_id] => 1
            [username] => testuser123
        )

    [4] => Array
        (
            [year] => 20
            [month] => 12
            [gender] => 2
            [votes] => 2
            [user_id] => 2
            [username] => prettygirl
        )
     [5] => Array
        (
            [year] => 20
            [month] => 12
            [gender] => 2
            [votes] => 7
            [user_id] => 55
            [username] => anotheruser
        )

     [6] => Array
        (
            [year] => 20
            [month] => 12
            [gender] => 2
            [votes] => 3
            [user_id] => 31
            [username] => anotheruser22
        )

)
I want to figure out which user received the most votes for a given year, month, gender, combination. Ignoring ties, how can I extract the highest vote count for each year/month/gender combo? A new result set will be generated each month.

I've been banging my head on this all day and can't come up with a working solution.

ModeSix
Mar 14, 2009

Biowarfare posted:

some abomination similar to

php:
<?
$counter = [];
foreach ($array as $obj) {
    $key = "{$obj['year']}_{$obj['month']}_{$obj['gender']}";
    if (!array_key_exists($key, $counter)) {
        $counter[$key] = $obj;
    } else {
        if ((int) $counter[$key]['votes'] < (int) $obj['votes']) { $counter[$key] = $obj; }
    }
}
?>
$counter will be k-v, k of year/month/gender and v of the winning object
explode('_', k value)

< makes it so that first into the tie wins (eg: checking votes = 1, 3, 4, 1, 4 means the first 4 will win), change <= if last


... this is assuming you don't want to use a proper database for it (?)
I'm actually pulling this from a MySQL database using the below query, if you know how to make it only deliver the highest value for each year/month/gender combination that would solve this. I don't know enough advanced SQL to make it do it on the database, though I know that's a better solution.

I already asked on the SQL thread, and I thought I understood the answer, but don't!

code:
SELECT be.year, 
       be.month, 
       be.gender, 
       COUNT(bv.votefor_id) as votes, 
       be.user_id, 
       u.username, 
       be.image 
FROM   datingsite_beauty_entries be 
       INNER JOIN datingsite_beauty_votes bv 
               ON be.user_id = bv.votefor_id 
       INNER JOIN datingsite_users u 
               ON be.user_id = u.id 
WHERE  be.year = bv.year 
       AND be.month = bv.month 
GROUP  BY bv.votefor_id, 
          be.year, 
          be.month 
ORDER  BY year DESC, 
          month DESC, 
          gender ASC, 
          votes DESC 

ModeSix
Mar 14, 2009

Jeffrey of YOSPOS posted:

Here's an example from the post above for comparison:

.......


I checked this in both light and dark mode and I don't think the code=php tag is a good solution for PHP code.

It reaches mostly acceptable levels on light mode, but downright bad on dark mode.

ModeSix
Mar 14, 2009

astral posted:

How about now? Thanks to some good feedback in the technical forum, the code highlighting system has been updated. Additional code highlighting improvements will be forthcoming.

The blue on blue is still... difficult to read.

This is using the PHP tag.


It's like there's a smurf hiding in a blueberry patch. :v:

On the code=php tag it's super easy to read.

You can check this post as a reference: https://forums.somethingawful.com/showthread.php?noseen=1&threadid=2802621&pagenumber=219&perpage=40#post514831916

ModeSix fucked around with this message at 02:47 on Jul 2, 2021

ModeSix
Mar 14, 2009

Good Sphere posted:

I'm trying to get php installed on macOS, using Intel processor. I've had it before, but I understand there has been some changes, and the brew install is your best bet. Seems to be installed, although php is showing the script instead of the rendered page in my browser. I'm using localhost in the address bar.

I followed these instructions: https://github.com/shivammathur/homebrew-php

Your best and easiest bet might be XAMPP: https://www.apachefriends.org/download.html

ModeSix
Mar 14, 2009

It's funny, I just solved this problem for myself just yesterday on something I was working on.

You could also do something like this:

code:
$deposit = array_column($item_data, 'deposit');
deposit is an object inside the array, so not directly accessible but you can get it by column name, maybe?

ModeSix
Mar 14, 2009

Good Sphere posted:

Thanks for the info. I tried your suggestions. Used echo(shell_exec("open -a 'myAppName' file.txt"));, also with full path, and even without specifying the app name. Maybe it's how things are configured on the php end.

Since you're curious, here's a some background to why I want to do this. I have javascript that calls a certain numbered function that renders graphics frame by frame. Those images get saved with an ajax call to php. I string the images into a video using ffmpeg via command. First, it would be nice to be able to start making that video right away when the images are all rendered with that ffmpeg command. That's not too much of a problem though. The real reason is that I want an interface where I can make new files; one for each image generation function. These functions are kind of containers for little programs that make these animation frames. So if I want to edit one, I could just click in a list and hit open.

There's more to it than that too. They are just function names with arbitrary numbers. I could keep it that way, but in a sql database, I could have different things like titles for the functions (which I could change later without having the program affected), and descriptions.

In the php.ini search for disable_functions and make sure shell_exec is not listed there. If it is, remove it, save and restart XAMPP.



ModeSix fucked around with this message at 01:21 on Jul 16, 2022

ModeSix
Mar 14, 2009

edit: nevermind, it didn't actually do it right.

ModeSix fucked around with this message at 21:42 on Feb 25, 2023

ModeSix
Mar 14, 2009

Here's a solution ChatGPT gave me after a bit of massaging.

php:
<?php

// Step 1: Create an array of 10,000 nodes
$nodes = array();
for ($i 0$i 10000$i++) {
    $nodes[$i] = array();
}

// Step 2: Generate random connections for each node
$letters range('A''U');

// Step 2a: Create the "main group" of nodes
$main_group = array();
for ($i 0$i 1000$i++) {
    $main_group[] = rand(09999);
}
shuffle($main_group);
foreach ($main_group as $i => $node) {
    $num_connections min(count($main_group) - 1rand(120));
    $available_connections array_diff($main_group, array($node));
    shuffle($available_connections);
    for ($j 0$j $num_connections$j++) {
        $connection_letter $letters[$j];
        $connection_node $available_connections[$j];
        $nodes[$node][$connection_letter] = $connection_node;
        $nodes[$connection_node][$connection_letter] = $node;
    }
}

// Step 2b: Connect the remaining nodes to the main group
$remaining_nodes array_diff(array_keys($nodes), $main_group);
foreach ($remaining_nodes as $i => &$node) {
    $num_connections rand(120);
    $available_connections array_merge($main_grouparray_diff($remaining_nodes, array($node)));
    shuffle($available_connections);
    for ($j 0$j $num_connections$j++) {
        $connection_letter $letters[$j];
        $connection_node $available_connections[$j];
        $nodes[$node][$connection_letter] = $connection_node;
        $nodes[$connection_node][$connection_letter] = $node;
    }
}
?>

It appears to work.

ModeSix fucked around with this message at 03:01 on Feb 27, 2023

Adbot
ADBOT LOVES YOU

ModeSix
Mar 14, 2009

Ranzear posted:

You'll spend more time futzing with it and then vetting what it spits out than it would take to write it yourself, cleaner to read, faster, and more expansible, in the first place.

I definitely agree with this statement and can attest I had to get it to redo a few things a few times to get it to a useable state.

The code I put up above is by no means optimal or easy to read. It gets the job done, sub optimally, but as Ranzear said how expandable or flexible it is is likely low.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply