Jump to content

gizmola

Administrators
  • Posts

    5,878
  • Joined

  • Last visited

  • Days Won

    139

Everything posted by gizmola

  1. Good to know that you have determined that you only have one row in there. That is progress, if you are sure. That code does not insure you only have one row for a given username. That should be enforced at the database level by adding a unique index to the users.username table. You can do that with phpMyAdmin/workbench etc. or learn to write the SQL statement that does it. The tools simply write the DDL for you and execute it, but SQL DDL is not difficult to read or understand. Here's the actual statement: CREATE UNIQUE INDEX users_username_idx ON users (username) If this can not be run due to a duplicate index error, then you would be covered. If however you get an error because there are already multiple duplicate usernames in the table, it will not be possible to create the index, and you would need to clean that up before you can create the index. Back to your statement: it only checks if there is one and only one row in the database. If there is an error in your current code (and you have stated that there is) it's possible that more than one identical row exists. In that case, your code will generate an incorrect result. Even though there is actually > 1 user rows with that username and pw, your code treats that situation as if there are none.
  2. I didn't attack you. I took a lot of time to explain to you why others have requested information or changes you seem resistant to. This is not how to engage people to help you (for free no less). If I want to attack someone in a forum reply, I can do a pretty good job of that, but that is not why I'm here. I've actually answered easily 10k questions from beginners or intermediate developers like yourself. Did you carefully read my reply? I took a good amount of time explaining the urgency and importance of writing modern safe mysqli code. Please read this, modify your code and provide an update. In the process it might fix whatever issue you have, but if it doesn't, people will most likely continue to aid you, if you show the effort you've made to learn and implement their suggestions. Last but not least, are you using a tutorial to base your code on? If so, let us know which one you are following. Based on the mysql code, that could be contributing to your problems.
  3. This is not how to do this sort of thing in my opinion. You are simply talking about related products, not versions. You can either handle that as a hierarchy (not as flexible) or a full A -> B relationship table. This is typically what is done in enterprise systems that are sold for large commercial enterprises, or in an ERP. Product >--- ProductProduct >-- Product V | RelationshipType RelationshipType examples: Package Item Sequel/Replacement Part ProductProduct basic structure ----------------------------------- id (pk) parent_product_id (fk Product) child_product_id (fk Product) relationshipType_id (fk Relationship Type) created_on I don't know what you mean by this. Are you saying you have 3 product subtypes and each one is named "foo", and then you have "foo_version"? Or are you just saying you have a subtype column in Product, and this has the word "foo" in it for "foo" items? No idea what you are talking about. You seem to have a proliferation of tables, and I'm arguing that you can do the same things with a more generic approach that would actually be fewer tables. If you insist on putting pricing in each individual subtype table, you are creating more tables. That's not better or fewer tables. The other thing you are glossing over is the procedural cost of generating a product catalog, or storing data in that catalog. Rather than having one join that gets a product and its pricing, in your system, there has to be separate queries at minimum for each product subtype. That is not good. Anytime you have to fall down to procedural code to do something, you have not made the system database driven. It's going to be duplicative logic with a proliferation of code to do just about anything you need. Again, just my 2 cents, but I'm feeling at this point we are retreading the same ground for a bit, and the back in forth has a lot to do with your lack of presentation of an ERD. I would never go into a development project without an ERD, not just because it's a picture, but also because it will aid you with DDL generation, and improvements. There is nothing more painful from a development standpoint than having to fix a database that you come to find is incorrect, especially if you already have production data in it. I don't know if you don't have an ERD, and that's why we haven't seen one, but if this is a serious business project for you, then you really should.
  4. Correct. A subtype is an object oriented programming concept. A subtype is a derived/child class. Relational databases only deal with relational algebra. There is no SQL for inheritance. When you are designing the tables, you have to ask yourself the question of what the attribute is a property of. Is it a property of a Product (yes!) or only a property of a membership. If all your products that aren't memberships are going to be free.. well then ok I don't know what you mean by order stream. If we can't look at an ERD there are going to be misunderstandings. I don't know if you are denormalizing or not. I was referring to relational patterns, and I would consider your proposition to make a subtype table for some reason, when you aren't making subtype tables for all the "product types" would be an anti -pattern. But again, I don't know what your ERD looks like. I do know when you are designing something that will require procedural code just to understand how and when queries would be formulated. Pricing seems to be the same sticking point. You seem to think that pricing needs to be in a product subtype table, and I know that isn't the case. But it's your system so --- You named your product subtype table member_plan. It should be named product_membership (again assuming that 'membership' is your subtype of product. Exactly. And that includes pricing, because pricing, even versioned pricing, is an attribute of all products, not just membership products. Well, again, you might have a good argument for this, but I doubt there would or should be that many columns. I've learned over the years to err on the side of having too few columns rather than too many. You can always add a column, but it's beneficial to question each and every byte you use.
  5. Here's one obvious potential issue with your code. $query = "SELECT * FROM users WHERE username='$username' AND password='$password'"; $results = mysqli_query($db, $query); if (mysqli_num_rows($results) == 1) { This is fine so long as there is one and only one row in the db with that username and password. We don't know if that's actually true in your case. Typically you might have a unique constraint/index on username to prevent this, but if you don't have that, you might have unknowingly entered 2+ rows with the same username and password. This test is going to fail in that case, at the moment you have 2 rows. Obviously you don't want this to be possible, but without knowing how your user table is set up, we can't be sure.
  6. With all due respect to you, you are an admitted novice. Many of the people who have replied to you have developed systems with php and mysql professionally for years if not decades. People are asking you to verify some things for a reason. When I'm diagnosing something, I may be running through a mental checklist that includes a vast number of variables you aren't aware of, having coded for a living. You think that it might not be saving the data (but you aren't sure) It could be saving the data, but just not reading it back You need error reporting turned on to see if there are hidden runtime errors or warnings that will pinpoint a problem Many people here will help you with your problem, but I will not for one reason only. I don't need you to change to PDO, although I agree it's a far nicer API to work with than mysqli. But I absolutely will not help anyone who is not using bound parameters and prepared statements. It's dangerous obsolete coding. Your code (including storing the passwords as md5 hashes without even a salt!!! harkens back to a time 10+ years in the past. Whether this is a hobby or not, there is no reason to write obsolete code when you can just as easily write modern code. It would take at most 10 minutes to read about the technique and add the code you would need to utilize that parameters. I can't be bothered to help someone debug something that is teaching them an improper practice any more than an electrician would teach someone how to work on wiring in their home, and not insist they turn off the circuit breaker and verify it was off with a multimeter. I'm not saying that you are the type of person who is stubborn and can't or won't try and learn, but in the past when people start to react the way you did as illustrated by your quoted comment, it's someone who is stubborn and easily offended. That does not lead to learning and a valuable expenditure of my time or the time of the other volunteers who answer questions.
  7. Apparently text is also a good way to store the eventtime too. I didn't notice that. 🐳
  8. Hurray for repeating groups and rampant denormalization. Maybe just use a flat file or a spreadsheet?
  9. And what do you plan to do with the survey?
  10. This is database design terminology. A relation is the connection between 2 tables. In a relational database there is no such thing as a subtype. You can support the idea by having something like product_type, where the various subtypes you want to support are enumerated. Then for every subtype, you need a table. So in your case, the one we know about is "membership". Let's say that Product.type can have these values: Article Membership Clothing Then you would expect to have these tables: Product_article Product_membership Product_clothing You make a dependent relationship between Product and the subtype table, so that it's primary key is the same as the Product primary key. The "type" column in Product indicates which subtype table you would expect needed to be joined to. ORM's like Doctrine2 and Laravel Eloquent have a degree of support for this. Pricing should not be related to the subtype table, but instead be related to the Parent product table. When a membership is ordered, you would have the Product linked to the order, not the subtype table. There are practical reasons for designing things this way. I can't write a full relational database design treatise on these design patterns or why they work and are maintainable, database driven and easy to code for. I don't think that's fancy. I'd probably have an attribute in the Product_membership subtype table that could be as simple as a flag that indicates "plan_can_be_renewed" or something like that. Again the aging logic of plan renewals would take this into account when the logic runs to offer the member a renewal. This would really be the reward for the pain of engineering around a subtype table schema which defies standard sql joining of tables. Overall, it seems that most of your tables are just named in a way that is specific to your ideas about how you plan to implement memberships. Hopefully I've headed you off a mistake in regards to Product and Member_plan. The way to think of member_plan is that it's a home for those things that are specific to a membership. As I mentioned I wouldn't name it the way you are planning to name it. It should be named conventionally to indicate the product type as I explained above. I would probably tell you to use common relational design patterns. I'd also point out places where you are not normalizing. I've done much more database design work as a system architect than most people, so I have a lot of experience with relational design patterns and understand the limitations and implications of a series of tables. Your tables (albeit with some different naming) seem to be close to what I'd assume you would need for a system like this, with the main issue being what appears to me to be a misunderstanding of relational subtyping. Even with that, you absolutely would expect to have an order for a membership with a lineitem for that membership with the foreign key to the product, and the price paid in the lineitem + tax if applicable. Nothing should go into Product_membership that isn't entirely specific to memberships. Things that should be in Product and not in membership would include status (active, inactive, deleted), category_id, name, description, manufacturer id, taxability, etc. Also as I mentioned previously, I'd expect that there would be a price table related to Product, with the price and from_to dates. In this case I would severely question the need for a subtype table extension, if there is only an attribute or 2 specific to membership. If it's only going to be "duration" and "can_be_renewed" flag, I don't think I'd bother. I'd just stick a couple of extra columns in Product.
  11. IPV6 is a 128 bit number, broken for representation into 8 16 bit blocks. Since each byte requires 2 hex digits, a 16 bit block requires 4 hex chars. This range of numbers has 2 issues I see: Only 6 blocks. Some of the 6 bocks have only 1 hex digit. It is ok to omit "continguous" zero blocks, and replace them with '::'. This is the most confusing part of ipv6, because it doesn't matter how many contiguous '0000' blocks you have. It can be 2,3,4 etc. You can only use that trick one time however in a number. ipv6 parsing figures this out and expands the '::' to the correct number of zero blocks. Thus the example #967 is invalid because there are only 5 blocks. 2a04:4540:8202:ce00:7c50: This would be valid 2a04:4540:8202:ce00:7c50:: # Is actually equivalent to 2a04:4540:8202:ce00:7c50:0000:0000:0000 See if something is messed up that is stripping off an ending '::' and reducing it to ':' ipv6 numbering supports "zero suppression" in a few ways. You can remove leading zeros OR you can compress 4 zeros into one, OR you can omit a block of zeros (one time, I think) in a number as per the example above. So testing #757, again we have only 6 groups, when we need 8, so once again, adding an end '::' will make it valid: 2a02:0c7f:1804:b000:4970:6:: #Equivalent to 2a02:0c7f:1804:b000:4970:0006:0000:0000
  12. I would want to see an ERD of the tables involved in this question. If order and subscription_details have no relationship to each other, then why do you have them both? A typical commerce system would at minimum have: Order --< lineitem This allows people to purchase multiple things in one order. The usual way this might be handled would be to have an item that describes the thing being purchased. So the extended model including lineitem: Order --< lineitem >-- Item Items I would expect: 1 Month Subscription 3 Month Subscription 6 Month Subscription 12 Month Subscription 2 Year Subscription Each of these will have a price, although the price usually would be in a seperate table related to item, broken out with an effective from-to date. So in conclusion, it looks like your subscription_plan = lineitem (although not generically capable of supporting sale of things other than subscriptions) and plan = item. I'm not sure why you are making this so specific to only subscriptions, nor am I clear how order fits into this. Having a lineitem date would be unusual in a system like this. If I order a stick of gum and a magazine on tuesday, I don't need a separate stick of gum date & magazine date, which is going to be the same as the order date. Renewals is an aging process in subscription systems. You run batch processes that do things like: -send out 1 month reminder -send out 15 days reminder -send out discount offers send out expiration notice -send out churn offers (come back and I'll offer you 10% off) etc. These operations don't require an end date. What they do require is a start date, and the subscription status and duration.
  13. Yes, it's a language construct that is part of javascript itself. One essential resource is Can I use? Very nice way of checking if the techniques
  14. In case you were wondering, the example provided is the implementation of an IFFE (I pronounce it IFFY but maybe that's just me). A very useful mechanic and design pattern. Once you grok it, you will find it very useful. To quote the page I linked: You may find yourself looking at all the global variables and functions you made to and finding this technique a great way of cutting down on those.
  15. I'm not sure what you are after there. Those are simply environment variables from the server running php. What is your server stack? Are you running IIS, Apache? What is the OS of the server? You stated that you have a simple login. What I've done in the past, is to have the login make LDAP calls to active directory to authenticate the user. Before you go down the LDAP road, If you are lucky and your environment intrinsically supports this, you could try to echo this value: echo "Current User is {$_SERVER['AUTH_USER']}";
  16. Lately I've been getting real annoyed with SO and some of the stupidity that goes on there. As it happens, I stumbled upon the author of the PhpDelusions PDO and MySqli tutorials SO profile, and discovered that he/she had been banned from SO apparently due to too many complaints from the clueless he's tried tirelessly to educate. SO Profile here. Had 146k rep, over 4 years and Hundreds of answers on php, pdo and mysqli. I know many if not all of the admins, mods and gurus have linked people to phpdelusions in the past. The old adage "no good deed goes unpunished" seems applicable.
  17. Yes, you can make LDAP calls in php, to your AD. That would likely be the way I would do it from what little you've said. AD is compliant with LDAP.
  18. You bootstrap requires routing. Essentially routing is the piece that takes a url and matches it to a controller. Some examples to look at: https://symfony.com/doc/current/routing.html https://laravel.com/docs/7.x/routing https://book.cakephp.org/3/en/development/routing.html There's lots of Routing components/classes out there, but here is one that might make for a good model for you: https://altorouter.com/
  19. It seems from your logs you are close though.
  20. I am not great at that either. I have 2 2015 Macbook Pros I use, both on Mojave, but I have decided not to try and upgrade them to Catalina, as I read that it broke a bunch of 16bit apps, and I don't want to spend time or money trying to upgrade things that currently work fine for me. The main thing I am wondering about is that you are starting up a cli app, and there are some other vsc settings that might be relevant to the cli like: program: Path to the script that should be launched args: Arguments passed to the script cwd: The current working directory to use when launching the script runtimeExecutable: Path to the PHP binary used for launching the script. By default the one on the PATH. runtimeArgs: Additional arguments to pass to the PHP binary externalConsole: Launches the script in an external console window instead of the debug console (default: false) env: Environment variables to pass to the script
  21. It's fairly obvious I think. Your $text variable has single quotes in it. You are then trying to insert it: $db->query("INSERT INTO gangevents VALUES(...,'$text')"); Because you are not escaping the $text, you have conflicting single quotes because at runtime the $csscode... becomes: viewuser.php?u=666' id='member' Notice the single quotes around 'member'. Really you should be changing all your code to use parameters. That is a countermeasure for SQL injection exploits AND eliminates the need for you to escape input. But in the near term you could fix this by making sure that the code that generates id='member' instead generates id="member"
  22. The Rewrite looks fine to me. Oops, yeah should be (list|gallery) For aliasing I would suggest that rather than using rewrite, use mod_alias with the alias_match directive
  23. Maxxd is right. You should never do this, but it's a common mistake that is hard to recover from unfortunately. You should always store datetime values as UTC, and this should be the timezone of the server OS, php and mysql. Once you know it's in UTC, you convert the date using a timezone for the purposes of display.
  24. This is one of the reasons I don't use bactics around column names unless they are absolutely necessary (wihich is rare). $query = "UPDATE greencard SET comments = '$comments', sent = '$sent' WHERE hospitalnumber = '$hospitalnumber' and PIN= '$PIN'"; Make sure that follow Requinix's instructions and change this code to use parameters and prepared statements. There is no excuse to write new code this way!
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.