Cách nhận xếp hạng trung bình trong PHP

Cách cơ bản để tính giá trị trung bình đơn giản là cộng mọi thứ lại và chia cho tổng số giá trị, vì vậy

$total = array_sum[$ratings];
$avg = $total/count[$ratings];
printf['The average is %.2f', $avg];

Logic tương tự áp dụng cho các giá trị của bạn, chỉ là bạn cần xếp hạng trung bình, vì vậy, hãy lấy tổng số "điểm xếp hạng" đã được đưa ra và chia chúng cho tổng số phiếu bầu

$totalStars = 0;
$voters = array_sum[$ratings];
foreach [$ratings as $stars => $votes]
{//This is the trick, get the number of starts in total, then
 //divide them equally over the total nr of voters to get the average
    $totalStars += $stars * $votes;
}
printf[
    '%d voters awarded a total of %d stars to X, giving an average rating of %.1f',
    $voters,
    $totalStars,
    $totalStars/$voters
];

Như bạn có thể thấy ở đây, đầu ra là

3658 cử tri đã trao tổng cộng 17054 sao cho X, xếp hạng trung bình là 4. 7

Giải pháp liên quan

Php – Cách ngăn SQL injection trong PHP

Cách chính xác để tránh các cuộc tấn công SQL injection, bất kể bạn sử dụng cơ sở dữ liệu nào, là tách dữ liệu khỏi SQL, để dữ liệu vẫn là dữ liệu và sẽ không bao giờ được trình phân tích cú pháp SQL diễn giải thành các lệnh. Có thể tạo câu lệnh SQL với các phần dữ liệu được định dạng chính xác, nhưng nếu bạn không hiểu đầy đủ chi tiết, bạn nên luôn sử dụng câu lệnh đã chuẩn bị sẵn và truy vấn được tham số hóa. Đây là các câu lệnh SQL được máy chủ cơ sở dữ liệu gửi đến và phân tích cú pháp riêng biệt với bất kỳ tham số nào. Bằng cách này, kẻ tấn công không thể tiêm SQL độc hại

Về cơ bản, bạn có hai lựa chọn để đạt được điều này

  1. Sử dụng PDO [đối với mọi trình điều khiển cơ sở dữ liệu được hỗ trợ]

     $stmt = $pdo->prepare['SELECT * FROM employees WHERE name = :name'];
    
     $stmt->execute[[ 'name' => $name ]];
    
     foreach [$stmt as $row] {
         // Do something with $row
     }
    
  2. Sử dụng MySQLi [dành cho MySQL]

     $stmt = $dbConnection->prepare['SELECT * FROM employees WHERE name = ?'];
     $stmt->bind_param['s', $name]; // 's' specifies the variable type => 'string'
    
     $stmt->execute[];
    
     $result = $stmt->get_result[];
     while [$row = $result->fetch_assoc[]] {
         // Do something with $row
     }
    

Nếu bạn đang kết nối với cơ sở dữ liệu không phải MySQL, thì có tùy chọn thứ hai dành riêng cho trình điều khiển mà bạn có thể tham khảo [ví dụ:

4
0 và
4
1 cho PostgreSQL]. PDO là tùy chọn phổ quát

Thiết lập kết nối chính xác

Lưu ý rằng khi sử dụng PDO để truy cập cơ sở dữ liệu MySQL, các câu lệnh chuẩn bị thực không được sử dụng theo mặc định. Để khắc phục điều này, bạn phải tắt mô phỏng các câu lệnh đã chuẩn bị. Một ví dụ về việc tạo kết nối bằng PDO là

$dbConnection = new PDO['mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'password'];

$dbConnection->setAttribute[PDO::ATTR_EMULATE_PREPARES, false];
$dbConnection->setAttribute[PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION];

Trong ví dụ trên, chế độ lỗi không thực sự cần thiết, nhưng bạn nên thêm nó vào. Bằng cách này, tập lệnh sẽ không dừng lại với

4
2 khi có sự cố xảy ra. Và nó mang lại cho nhà phát triển cơ hội
4
3 bất kỳ [các] lỗi nào
4
4n thành
4
5

Tuy nhiên, điều bắt buộc là dòng

4
6 đầu tiên, yêu cầu PDO tắt các câu lệnh đã chuẩn bị được mô phỏng và sử dụng các câu lệnh đã chuẩn bị thực sự. Điều này đảm bảo rằng câu lệnh và các giá trị không được PHP phân tích cú pháp trước khi gửi nó đến máy chủ MySQL [khiến kẻ tấn công không có cơ hội tiêm SQL độc hại]

Mặc dù bạn có thể đặt

4
7 trong các tùy chọn của hàm tạo, điều quan trọng cần lưu ý là các phiên bản PHP 'cũ' [trước 5. 3. 6] âm thầm bỏ qua tham số bộ ký tự trong DSN

Giải trình

Câu lệnh SQL bạn chuyển đến

4
8 được máy chủ cơ sở dữ liệu phân tích cú pháp và biên dịch. Bằng cách chỉ định các tham số [có thể là
4
9 hoặc tham số được đặt tên như
$totalStars = 0;
$voters = array_sum[$ratings];
foreach [$ratings as $stars => $votes]
{//This is the trick, get the number of starts in total, then
 //divide them equally over the total nr of voters to get the average
    $totalStars += $stars * $votes;
}
printf[
    '%d voters awarded a total of %d stars to X, giving an average rating of %.1f',
    $voters,
    $totalStars,
    $totalStars/$voters
];
50 trong ví dụ trên], bạn cho công cụ cơ sở dữ liệu biết nơi bạn muốn lọc. Sau đó, khi bạn gọi
$totalStars = 0;
$voters = array_sum[$ratings];
foreach [$ratings as $stars => $votes]
{//This is the trick, get the number of starts in total, then
 //divide them equally over the total nr of voters to get the average
    $totalStars += $stars * $votes;
}
printf[
    '%d voters awarded a total of %d stars to X, giving an average rating of %.1f',
    $voters,
    $totalStars,
    $totalStars/$voters
];
51, câu lệnh đã chuẩn bị được kết hợp với các giá trị tham số mà bạn chỉ định

Điều quan trọng ở đây là các giá trị tham số được kết hợp với câu lệnh đã biên dịch, không phải là chuỗi SQL. SQL injection hoạt động bằng cách lừa tập lệnh bao gồm các chuỗi độc hại khi nó tạo SQL để gửi đến cơ sở dữ liệu. Vì vậy, bằng cách gửi SQL thực riêng biệt với các tham số, bạn sẽ hạn chế rủi ro kết thúc bằng thứ mà bạn không có ý định

Bất kỳ tham số nào bạn gửi khi sử dụng câu lệnh đã chuẩn bị sẽ chỉ được coi là chuỗi [mặc dù công cụ cơ sở dữ liệu có thể thực hiện một số tối ưu hóa để tất nhiên, tham số cũng có thể kết thúc dưới dạng số]. Trong ví dụ trên, nếu biến

$totalStars = 0;
$voters = array_sum[$ratings];
foreach [$ratings as $stars => $votes]
{//This is the trick, get the number of starts in total, then
 //divide them equally over the total nr of voters to get the average
    $totalStars += $stars * $votes;
}
printf[
    '%d voters awarded a total of %d stars to X, giving an average rating of %.1f',
    $voters,
    $totalStars,
    $totalStars/$voters
];
52 chứa
$totalStars = 0;
$voters = array_sum[$ratings];
foreach [$ratings as $stars => $votes]
{//This is the trick, get the number of starts in total, then
 //divide them equally over the total nr of voters to get the average
    $totalStars += $stars * $votes;
}
printf[
    '%d voters awarded a total of %d stars to X, giving an average rating of %.1f',
    $voters,
    $totalStars,
    $totalStars/$voters
];
53 thì kết quả sẽ chỉ là tìm kiếm chuỗi
$totalStars = 0;
$voters = array_sum[$ratings];
foreach [$ratings as $stars => $votes]
{//This is the trick, get the number of starts in total, then
 //divide them equally over the total nr of voters to get the average
    $totalStars += $stars * $votes;
}
printf[
    '%d voters awarded a total of %d stars to X, giving an average rating of %.1f',
    $voters,
    $totalStars,
    $totalStars/$voters
];
54 và bạn sẽ không nhận được một bảng trống

Một lợi ích khác của việc sử dụng các câu lệnh đã chuẩn bị là nếu bạn thực hiện cùng một câu lệnh nhiều lần trong cùng một phiên thì nó sẽ chỉ được phân tích cú pháp và biên dịch một lần, giúp bạn tăng tốc độ

Ồ, và vì bạn đã hỏi về cách thực hiện cho phần chèn, đây là một ví dụ [sử dụng PDO]

 $stmt = $pdo->prepare['SELECT * FROM employees WHERE name = :name'];

 $stmt->execute[[ 'name' => $name ]];

 foreach [$stmt as $row] {
     // Do something with $row
 }
0

Câu lệnh đã chuẩn bị có thể được sử dụng cho các truy vấn động không?

Mặc dù bạn vẫn có thể sử dụng các câu lệnh đã chuẩn bị cho các tham số truy vấn, nhưng bản thân cấu trúc của truy vấn động không thể được tham số hóa và một số tính năng truy vấn nhất định không thể được tham số hóa

Đối với những trường hợp cụ thể này, điều tốt nhất cần làm là sử dụng bộ lọc danh sách trắng để hạn chế các giá trị có thể

 $stmt = $pdo->prepare['SELECT * FROM employees WHERE name = :name'];

 $stmt->execute[[ 'name' => $name ]];

 foreach [$stmt as $row] {
     // Do something with $row
 }
1

Php – Băm và muối an toàn cho mật khẩu PHP

TUYÊN BỐ MIỄN TRỪ TRÁCH NHIỆM. Câu trả lời này được viết vào năm 2008

Kể từ đó, PHP đã cung cấp cho chúng tôi

$totalStars = 0;
$voters = array_sum[$ratings];
foreach [$ratings as $stars => $votes]
{//This is the trick, get the number of starts in total, then
 //divide them equally over the total nr of voters to get the average
    $totalStars += $stars * $votes;
}
printf[
    '%d voters awarded a total of %d stars to X, giving an average rating of %.1f',
    $voters,
    $totalStars,
    $totalStars/$voters
];
55 và
$totalStars = 0;
$voters = array_sum[$ratings];
foreach [$ratings as $stars => $votes]
{//This is the trick, get the number of starts in total, then
 //divide them equally over the total nr of voters to get the average
    $totalStars += $stars * $votes;
}
printf[
    '%d voters awarded a total of %d stars to X, giving an average rating of %.1f',
    $voters,
    $totalStars,
    $totalStars/$voters
];
56 và kể từ khi được giới thiệu, chúng là phương pháp kiểm tra và băm mật khẩu được đề xuất

Lý thuyết của câu trả lời vẫn là một đọc tốt mặc dù

TL; DR

Không

  • Không giới hạn những ký tự mà người dùng có thể nhập cho mật khẩu. Chỉ có những kẻ ngốc mới làm điều này
  • Không giới hạn độ dài của mật khẩu. Nếu người dùng của bạn muốn một câu có supercalifragilisticexpialidocious trong đó, đừng ngăn họ sử dụng nó
  • Không tước hoặc thoát HTML và các ký tự đặc biệt trong mật khẩu
  • Không bao giờ lưu trữ mật khẩu người dùng của bạn ở dạng văn bản thuần túy
  • Không bao giờ gửi email mật khẩu cho người dùng của bạn trừ khi họ bị mất mật khẩu và bạn đã gửi một mật khẩu tạm thời
  • Không bao giờ đăng nhập mật khẩu dưới bất kỳ hình thức nào
  • Không bao giờ băm mật khẩu bằng SHA1 hoặc MD5 hoặc thậm chí SHA256. Các cracker hiện đại có thể vượt quá 60 và 180 tỷ hash/giây [tương ứng]
  • Đừng trộn bcrypt và với đầu ra thô của hàm băm [], hãy sử dụng đầu ra hex hoặc base64_encode nó. [Điều này áp dụng cho bất kỳ đầu vào nào có thể có một
    $totalStars = 0;
    $voters = array_sum[$ratings];
    foreach [$ratings as $stars => $votes]
    {//This is the trick, get the number of starts in total, then
     //divide them equally over the total nr of voters to get the average
        $totalStars += $stars * $votes;
    }
    printf[
        '%d voters awarded a total of %d stars to X, giving an average rating of %.1f',
        $voters,
        $totalStars,
        $totalStars/$voters
    ];
    
    57 lừa đảo trong đó, điều này có thể làm suy yếu nghiêm trọng tính bảo mật. ]

làm

  • Sử dụng scrypt khi bạn có thể;
  • Sử dụng PBKDF2 nếu bạn không thể sử dụng bcrypt hoặc scrypt, với hàm băm SHA2
  • Đặt lại mật khẩu của mọi người khi cơ sở dữ liệu bị xâm phạm
  • Triển khai độ dài tối thiểu hợp lý từ 8-10 ký tự, đồng thời yêu cầu ít nhất 1 chữ in hoa, 1 chữ in thường, một số và một ký hiệu. Điều này sẽ cải thiện entropy của mật khẩu, từ đó khiến mật khẩu khó bẻ khóa hơn. [Xem phần "Điều gì tạo nên một mật khẩu tốt?" để biết một số tranh luận. ]

Tại sao lại băm mật khẩu?

Mục tiêu đằng sau mật khẩu băm rất đơn giản. ngăn chặn truy cập độc hại vào tài khoản người dùng bằng cách thỏa hiệp cơ sở dữ liệu. Vì vậy, mục tiêu của việc băm mật khẩu là để ngăn chặn tin tặc hoặc kẻ bẻ khóa bằng cách khiến họ tốn quá nhiều thời gian hoặc tiền bạc để tính toán mật khẩu văn bản thuần túy. Và thời gian/chi phí là rào cản tốt nhất trong kho vũ khí của bạn

Một lý do khác khiến bạn muốn có một hàm băm tốt, mạnh mẽ trên tài khoản người dùng là để cho bạn đủ thời gian để thay đổi tất cả mật khẩu trong hệ thống. Nếu cơ sở dữ liệu của bạn bị xâm phạm, ít nhất bạn sẽ cần đủ thời gian để khóa hệ thống, nếu không thay đổi mọi mật khẩu trong cơ sở dữ liệu

Jeremiah Grossman, CTO của Whitehat Security, đã tuyên bố trên blog White Hat Security sau khi khôi phục mật khẩu gần đây yêu cầu phá vỡ mật khẩu bảo vệ bằng vũ lực

Thật thú vị, khi sống qua cơn ác mộng này, tôi đã học được RẤT NHIỀU điều mà tôi không biết về việc bẻ khóa, lưu trữ và độ phức tạp của mật khẩu. Tôi đã hiểu tại sao việc lưu trữ mật khẩu lại quan trọng hơn nhiều so với độ phức tạp của mật khẩu. Nếu bạn không biết mật khẩu của mình được lưu trữ như thế nào, thì tất cả những gì bạn thực sự có thể phụ thuộc vào là độ phức tạp. Đây có thể là kiến ​​thức phổ biến đối với các chuyên gia về mật khẩu và tiền điện tử, nhưng đối với chuyên gia InfoSec hoặc Bảo mật web trung bình, tôi thực sự nghi ngờ điều đó

[Nhấn mạnh của tôi. ]

Điều gì tạo nên một mật khẩu tốt?

Sự hỗn loạn. [Không phải tôi hoàn toàn tán thành quan điểm của Randall. ]

Nói tóm lại, entropy là mức độ thay đổi trong mật khẩu. Khi mật khẩu chỉ là các chữ cái La Mã viết thường, đó chỉ là 26 ký tự. Đó không phải là nhiều biến thể. Mật khẩu chữ và số tốt hơn, với 36 ký tự. Nhưng cho phép chữ hoa và chữ thường, với các ký hiệu, là khoảng 96 ký tự. Điều đó tốt hơn nhiều so với chỉ các chữ cái. Một vấn đề là, để làm cho mật khẩu của chúng ta dễ nhớ, chúng ta chèn các mẫu—làm giảm entropy. Ối

Entropy mật khẩu được xấp xỉ dễ dàng. Sử dụng đầy đủ các ký tự ascii [khoảng 96 ký tự có thể đánh máy] mang lại entropy là 6. 6 cho mỗi ký tự, mà 8 ký tự cho một mật khẩu vẫn còn quá thấp [52. 679 bit entropy] để bảo mật trong tương lai. Nhưng tin tốt là. mật khẩu dài hơn và mật khẩu có ký tự unicode thực sự làm tăng entropy của mật khẩu và khiến mật khẩu khó bẻ khóa hơn

Có một cuộc thảo luận dài hơn về entropy mật khẩu trên trang web Crypto StackExchange. Một tìm kiếm tốt trên Google cũng sẽ cho ra rất nhiều kết quả

Trong các nhận xét tôi đã nói chuyện với @popnoodles, người đã chỉ ra rằng việc thực thi chính sách mật khẩu có độ dài X với X nhiều chữ cái, số, ký hiệu, v.v., thực sự có thể giảm entropy bằng cách làm cho sơ đồ mật khẩu dễ đoán hơn. tôi thực sự đồng ý. Tính ngẫu nhiên, càng ngẫu nhiên càng tốt, luôn là giải pháp an toàn nhất nhưng ít đáng nhớ nhất

Theo những gì tôi có thể nói, việc tạo ra mật khẩu tốt nhất thế giới là Catch-22. Nó không đáng nhớ, quá dễ đoán, quá ngắn, quá nhiều ký tự unicode [khó gõ trên thiết bị Windows/Mobile], quá dài, v.v. Không có mật khẩu nào thực sự đủ tốt cho mục đích của chúng ta, vì vậy chúng ta phải bảo vệ chúng như thể chúng ở Fort Knox

Thực hành tốt nhất

Bcrypt và scrypt là những phương pháp hay nhất hiện nay. Scrypt sẽ tốt hơn bcrypt trong thời gian tới, nhưng nó chưa được Linux/Unix hoặc máy chủ web chấp nhận như một tiêu chuẩn và chưa có bài đánh giá chuyên sâu nào về thuật toán của nó được đăng. Tuy nhiên, tương lai của thuật toán có vẻ đầy hứa hẹn. Nếu bạn đang làm việc với Ruby thì có một scrypt gem sẽ giúp bạn, và Node. js hiện có gói scrypt riêng. Bạn có thể sử dụng Scrypt trong PHP thông qua tiện ích mở rộng Scrypt hoặc tiện ích mở rộng Libsodium [cả hai đều có sẵn trong PECL]

Tôi thực sự khuyên bạn nên đọc tài liệu về chức năng mã hóa nếu bạn muốn hiểu cách sử dụng bcrypt hoặc tìm cho mình một trình bao bọc tốt hoặc sử dụng thứ gì đó như PHPASS để triển khai kế thừa hơn. Tôi đề xuất tối thiểu 12 vòng bcrypt, nếu không phải là 15 đến 18

Tôi đã thay đổi ý định sử dụng bcrypt khi tôi biết rằng bcrypt chỉ sử dụng lịch trình khóa của blowfish, với cơ chế chi phí thay đổi. Cái sau cho phép bạn tăng chi phí để bắt buộc sử dụng mật khẩu bằng cách tăng lịch trình khóa vốn đã đắt đỏ của blowfish

thực hành trung bình

Tôi gần như không thể tưởng tượng được tình huống này nữa. PHPASS hỗ trợ PHP 3. 0. 18 đến 5. 3, vì vậy nó có thể sử dụng được trên hầu hết mọi cài đặt có thể tưởng tượng được—và nên được sử dụng nếu bạn không biết chắc chắn rằng môi trường của mình có hỗ trợ bcrypt hay không

Nhưng giả sử rằng bạn hoàn toàn không thể sử dụng bcrypt hoặc PHPASS. Sau đó thì sao?

Hãy thử triển khai PDKBF2 với số vòng tối đa mà môi trường/ứng dụng/nhận thức người dùng của bạn có thể chịu đựng được. Con số thấp nhất tôi muốn giới thiệu là 2500 vòng. Ngoài ra, hãy đảm bảo sử dụng hash_hmac[] nếu có sẵn để làm cho thao tác khó tái tạo hơn

Thực hành trong tương lai

Đến trong PHP 5. 5 là một thư viện bảo vệ mật khẩu đầy đủ giúp loại bỏ mọi khó khăn khi làm việc với bcrypt. Trong khi hầu hết chúng ta đang mắc kẹt với PHP 5. 2 và 5. 3 trong hầu hết các môi trường phổ biến, đặc biệt là các máy chủ được chia sẻ, @ircmaxell đã xây dựng một lớp tương thích cho API sắp tới tương thích ngược với PHP 5. 3. 7

Tóm tắt mật mã & Tuyên bố miễn trừ trách nhiệm

Sức mạnh tính toán cần thiết để thực sự bẻ khóa mật khẩu băm không tồn tại. Cách duy nhất để máy tính "bẻ khóa" mật khẩu là tạo lại nó và mô phỏng thuật toán băm được sử dụng để bảo mật nó. Tốc độ của hàm băm có liên quan tuyến tính với khả năng bị cưỡng bức của nó. Tệ hơn nữa, hầu hết các thuật toán băm có thể dễ dàng song song hóa để thực hiện nhanh hơn. Đây là lý do tại sao các kế hoạch tốn kém như bcrypt và scrypt lại rất quan trọng

Bạn không thể thấy trước tất cả các mối đe dọa hoặc con đường tấn công, vì vậy bạn phải nỗ lực hết sức để bảo vệ người dùng của mình ngay từ đầu. Nếu không, bạn thậm chí có thể bỏ lỡ sự thật rằng mình đã bị tấn công cho đến khi quá muộn. và bạn chịu trách nhiệm. Để tránh tình huống đó, hãy hành động hoang tưởng để bắt đầu với. Tấn công phần mềm của chính bạn [trong nội bộ] và cố gắng đánh cắp thông tin đăng nhập của người dùng hoặc sửa đổi tài khoản của người dùng khác hoặc truy cập dữ liệu của họ. Nếu bạn không kiểm tra tính bảo mật của hệ thống, thì bạn không thể đổ lỗi cho ai ngoài chính mình

cuối cùng. Tôi không phải là một nhà mật mã học. Bất cứ điều gì tôi nói là ý kiến ​​của tôi, nhưng tôi tình cờ nghĩ rằng nó dựa trên lẽ thường của bạn. và đọc nhiều. Hãy nhớ rằng, càng hoang tưởng càng tốt, làm cho mọi thứ càng khó xâm nhập càng tốt, và sau đó, nếu bạn vẫn còn lo lắng, hãy liên hệ với một hacker mũ trắng hoặc nhà mật mã học để xem họ nói gì về mã/hệ thống của bạn

Làm cách nào để tính điểm trung bình trong PHP?

Tạo tệp PHP có tên star-rating. .
Chọn tất cả xếp hạng cho sản phẩm đã chọn hoặc đăng dưới dạng một mảng. .
Lấy tổng của tất cả các giá trị. .
Chia giá trị đó cho số lượng xếp hạng để có được xếp hạng trung bình. .
Lấy phần trăm của giá trị 3. 6 để điền vào 5 sao [3. 6/5]*100 = 72%

Làm cách nào để tính xếp hạng sao trong PHP?

hàm php tính toánStarRating[$like, $dislikes]{ $maxNumberOfStars = 5; . $totalRating = $like + $dislikes; . $likePercentageStars = [$like / $totalRating] * $maxNumberOfStars;

Làm cách nào để tính xếp hạng sao trung bình trong MySQL?

$i=$i+1;

Chủ Đề